在等待其他线程完成时,我们可以使用join
或CountdownLatch
。使用这两种机制中的任何一种的利弊是什么?
答案 0 :(得分:23)
如果您自己处理线程,则只能使用Thread.join
。大多数人选择不直接处理线程处理的细节,而是使用ExecutorService
来处理它们。 ExecutorService
并未直接显示他们执行任务的方式,因此您 使用CountDownLatch
:(假设您不想只是shutdown
整个服务,即。)
ExecutorService service = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(5);
for(int x = 0; x < 5; x++) {
service.submit(new Runnable() {
public void run() {
// do something
latch.countDown();
}
});
}
latch.await();
答案 1 :(得分:10)
另一个区别是在join()
之后,只有当联合线程完成执行时才能解除阻塞,而在CountDownLatch
中线程可以在线程完成时或者在任何时候基于任何线程减少计数条件。
通过这种方式,我们可以更好地控制线程的解锁,而不是仅仅依赖于连接线程的完成。
答案 2 :(得分:7)
join()正在等待另一个线程完成,而CountDownLatch是为另一个目的而设计的。如果使用CountDownLatch,您不必引用您正在等待的线程,因为我们必须使用join()。让我们假设您想要在至少有2名玩家可用的情况下开始游戏。在这种情况下,您可以使用countdownlatch。但是你不能轻易地使用连接来实现这一点,因为你没有其他线程(在这种情况下是播放器),你可以在其上编写join()。
答案 3 :(得分:6)
CountdownLatch是面向任务的 - 它与线程无关。可以将一大堆不相关的任务集提交给threadPool,并且CountdownLatch将确保每个集合通知发起者完成。 Join()是一个恼人的abberation,它将任务链接到线程,简单地说,应该从来没有输入过该语言。遗憾的是,一大堆热门的线程教程在第一页上提到了Join(),从而将线程引入新手作为死锁生成器并生成线程放克:(
答案 4 :(得分:4)
CountdownLatch
允许您将Item的实现更改为可以提交给Executor服务,而不是直接使用Threads。
CountDownLatch
类允许我们协调线程的启动和停止。典型用途如下:
Thread.join()
方法只允许您等待单个线程。)你可以看看这个 - &gt; http://javahowto.blogspot.com/2011/08/when-to-join-threads-with.html
这个 - &gt; A CountDownLatch's latch.await() method vs Thread.join()