Java около 100 параллельных потоков, управление памятью - PullRequest
9 голосов
/ 07 января 2010

Я пишу алгоритм оптимизации, который создает около 100 потоков. В настоящее время я запускаю их все одновременно (цикл for) и после этого говорю каждому потоку, что он должен присоединиться ().

Моя проблема сейчас в том, что каждый поток использует много памяти, поэтому исключение пространства кучи не займет много времени. Мне нужно какое-то планирование, но я не знаю, как его реализовать.

Я имею в виду что-то вроде этого: начинайте 10 потоков, и каждый раз, когда один из этих завершений начинает новый. Таким образом, всегда выполняется 10 потоков одновременно, пока не останется ни одного потока.

У кого-то есть идеи или они знают, как реализовать что-то подобное?

Большое спасибо и привет из Кельна

Marco

Ответы [ 4 ]

19 голосов
/ 07 января 2010

Используйте ThreadPoolExecutor с соответствующим максимальным размером пула.

4 голосов
/ 07 января 2010

Вот пример, с которого можно начать. Во-первых, что вам нужно импортировать:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

И что нужно добавить в свой метод:

    ExecutorService pool = Executors.newFixedThreadPool(10);
    for(final Task task: tasks) { 
        pool.execute(new Runnable() {
            @Override
            public void run() {
                task.execute();
            }
        });
    }
    pool.shutdown();
    while(!pool.awaitTermination(1, TimeUnit.SECONDS)) {
        System.out.println("Waiting for tasks to shutdown");
    }

Некоторые примечания по поводу вышеперечисленного:

  • Вам нужно будет реализовать свой собственный Класс задачи, который фактически реализует ваш алгоритм
  • Класс задач не должен просто иметь метод execute (на самом деле, если у него есть эта подпись, вы могли бы просто получить вашу задачу для реализации Runnable и избегайте анонимного внутреннего класса)
  • Вам нужно убедиться, что все, что вы используете правильно синхронизированы. Занятия в java.util.concurrent.atomic являются очень хорошо, если вы поделились государством вам нужно обновить (например, если вы хотите иметь счетчик на сколько задач вы обработали).
  • Как правило, вы хотите только столько потоки выполняются, как есть ядра / процессор на вашей машине. Часто производительность часто повышается, когда количество потоков уменьшается. Обычно вы используете больше потоков, только если ваши задачи тратят много времени заблокирован.
2 голосов
/ 07 января 2010

Вместо того, чтобы создавать новую тему для выполнения новой задачи, вам гораздо лучше:

  • есть очередь задач для выполнения (вместо запускаемых потоков)
  • использовать меньший пул потоков (как упомянуто Майклом) для обработки этих задач .

Разница в скорости и памяти огромна, потому что вам не нужно запускать и останавливать поток для каждой задачи.

Пакет java.util.concurrent объясняет все об этом. Книгу было бы легче читать, хотя: - (

1 голос
/ 07 января 2010

Рассмотрим количество ядер в машине, которую вы будете использовать. Производительность будет наилучшей, если количество потоков, которые вы обычно используете, равно количеству ядер. Как говорит KLE, используйте пул потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...