«простой» пул потоков в Java - PullRequest
3 голосов
/ 24 мая 2011

Я ищу простой объект, который будет содержать мои рабочие потоки, и мне нужно, чтобы он не ограничивал количество потоков и не поддерживал их в работе дольше, чем это необходимо. Но мне нужен метод, похожий на ExecutorService.shutdown(); (Ожидание завершения всех активных потоков, но не принятие новых)

так что, может быть, пул потоков - это не то, что мне нужно, поэтому я хотел бы получить толчок в правильном направлении. (поскольку они предназначены для поддержки потоков)

Дополнительные разъяснения о намерениях:

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

Ответы [ 2 ]

6 голосов
/ 24 мая 2011

Один из способов сделать то, что вам нужно, это использовать Callable с Future, который возвращает объект File завершенной загрузки.Затем передайте Future в другой Callable, который проверяет Future.isDone() и вращается до тех пор, пока не вернется true, а затем выполните все, что вам нужно сделать с файлом.Ваш вариант использования не уникален и очень аккуратно вписывается в возможности пакета java.util.concurrent .

Один интересный класс ExecutorCompletionService class , который делает именно то, что вы хотитес ожиданием результатов и продолжением дополнительных вычислений.

Служба CompletionService, которая использует предоставленный Исполнитель для выполнения задач.Этот класс организует, чтобы отправленные задачи после завершения помещались в очередь, доступную с помощью take.Класс является достаточно легким, чтобы его можно было использовать для временной обработки при обработке групп задач.

Примеры использования : Предположим, у вас есть набор решателей для определенной задачи, каждый из которых возвращает значение некоторого значения.введите Result и хотели бы запускать их одновременно, обрабатывая результаты каждого из них, которые возвращают ненулевое значение, при использовании некоторого метода (Result r).Вы могли бы написать это как:

   void solve(Executor e, Collection<Callable<Result>> solvers)
              throws InterruptedException, ExecutionException 
   {
       CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e);
       for (Callable<Result> s : solvers) { ecs.submit(s); }
       int n = solvers.size();
       for (int i = 0; i < n; ++i) 
       {
           Result r = ecs.take().get();
           if (r != null) { use(r); }
       }
   }

Вы не хотите неограниченный ExecutorService

Вы почти никогда не хотите разрешать неограниченные пулы потоков, так как онина самом деле может ограничить производительность вашего приложения, если количество потоков выходит из-под контроля.

Ваш домен ограничен дисковым или сетевым вводом-выводом или обоими, поэтому небольшого пула потоков будет достаточно.Вы не захотите пытаться читать сотни или тысячи входящих соединений с потоком на соединение.

Часть вашего решения, если вы получаете более чем несколько одновременных загрузок, - это исследовать1035 * package и прочесть о неблокирующем вводе / выводе.

0 голосов
/ 24 мая 2011

Есть ли причина, по которой вы не хотите повторно использовать потоки? Мне кажется, что проще всего было бы в любом случае использовать ExecutorService и позволить ему повторно использовать потоки.

...