2010-09-29 4 views
7

Я видел, что член stackoverflow предложил использовать Thread.join(), чтобы «основной» поток ожидал завершения двух задач «задачи».Метод latch.await() CountDownLatch vs Thread.join()

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

final CountDownLatch latch = new CountDownLatch(myItems.length); 

for (Item item : myItems) { 
    //doStuff launches a Thread that calls latch.countDown() as it's final act 
    item.doStuff(latch); 
} 

latch.await(); //ignoring Exceptions for readability 

ответ

8

Ваше решение легче масштабируется. Thread.join() был прекрасным способом решения вашей проблемы до того, как CountdownLatch и другие синхронизаторы были созданы.

С точки зрения удобочитаемости, я бы выбрал подход CountdownLatch для присоединения к каждому потоку. Это также позволяет вам изменить реализацию Item, чтобы, возможно, подчиниться службе Executor, а не напрямую использовать Threads.

0

Защелка обратного отсчета предпочтительна для одновременного запуска всех потоков одновременно.

8

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

Collection<Future<Void>> futures = new ArrayList<Future<Void>>(myItems.length()); 
for (Runnable item : myItems) { 
    futures.add(executor.submit(item, null)); 

for (Future<Void> future : futures) 
    future.get(); //easy to add a timeout here 

Конечная петля может быть легко разделена на полезный метод. Это инкапсулирует синхронизацию и упрощает добавление тайм-аутов.

Это также более применимо к общему случаю, где рабочие потоки фактически должны возвращать результат. (Если вас не волнует, что происходит с рабочими потоками, зачем их ждать?)

+0

Я всегда думал, что я должен заглянуть в класс Future?/Inteface? – Ivan

+0

Я пытаюсь понять, что предлагает CoundownLatch/CyclicBarrier через Future.get(). Полезный код полезности? – cs94njw

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