2014-02-01 4 views
0

У меня есть некоторое количество потребительских потоков, любое из которых также может выступать в качестве производителя. Как я должен знать, когда все они закончили свою работу?Остановить работу, если все потоки простаивают

class Worker extends Thread{ 
    void process(Task t){ 
     ... 
     if(needsMoreWork(t)){ 
      queue.addAll(extractTasks(t)); 
     } 
    } 
    public void run(){ 
     while(isRunning){ 
      Task t = queue.take();//I need to finish somehow. 
      process(t); 
     } 
    } 
    ... 
} 

ответ

5

Вместо использования Thread s вручную, представить свои задачи на ExecutorService и использовать CountDownLatch, CyclicBarrier или Phaser синхронизировать их, в зависимости от того, требуется ли многократные циклы вашей работы, и есть ли у вас то же самое количество компонентов задачи в каждом цикле.

В зависимости от того, в чем конкретно состоит ваш process, может быть рассмотрен вопрос: ForkJoinPool; он в основном завершает идею «выполнить эту же операцию над кучей предметов и собрать результаты».

+0

На самом деле я пытаюсь реализовать параллельный обход дерева. –

+1

@ guest-414 Тогда, в зависимости от того, что вы делаете, когда вы пересекаете это дерево, 'ForkJoinPool' может быть именно тем, что вы хотите. Это полезно, когда у вас ситуация с картой/уменьшением, поэтому, если ваш обход создает некоторую итоговую функцию по дереву, рекурсивная fork/join будет обрабатывать все параллелизм для вас. – chrylis

Смежные вопросы