CountDownLatch适⽤于在多线程的场景需要等待所有⼦线程全部执⾏完毕之后再做操作的场景。
举个例⼦,早上部⻔开会,有⼈在上厕所,这时候需要等待所有⼈从厕所回来之后才能开始会议。
public class CountDownLatchTest {
private static int num = 3;
private static CountDownLatch countDownLatch = new
CountDownLatch(num);
private static ExecutorService executorService =
Executors.newFixedThreadPool(num);
public static void main(String[] args) throws Exception{
executorService.submit(() -> {
System.out.println("A在上厕所");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
countDownLatch.countDown();
System.out.println("A上完了");
}
});
executorService.submit(()->{
System.out.println("B在上厕所");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
countDownLatch.countDown();
System.out.println("B上完了");
}
});
executorService.submit(()->{
System.out.println("C在上厕所");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
countDownLatch.countDown();
System.out.println("C上完了");
}
});
System.out.println("等待所有⼈从厕所回来开会...");
countDownLatch.await();
System.out.println("所有⼈都好了,开始开会...");
executorService.shutdown();
}
}
代码执⾏结果:
初始化⼀个CountDownLatch实例传参3,因为我们有3个⼦线程,每次⼦线程执⾏完毕之后调⽤countDown()⽅法给计数器-1,主线程调⽤await()⽅法后会被阻塞,直到最后计数器变为0,await()⽅法返回,执⾏完毕。他和join()⽅法的区别就是join会阻塞⼦线程直到运⾏结束,⽽CountDownLatch可以在任何时候让await()返回,⽽且⽤ExecutorService没法⽤join了,相⽐起来,CountDownLatch更灵活。
CountDownLatch基于AQS实现,volatile变量state维持倒数状态,多线程共享变量可⻅。
1. CountDownLatch通过构造函数初始化传⼊参数实际为AQS的state变量赋值,维持计数器倒数状态
2. 当主线程调⽤await()⽅法时,当前线程会被阻塞,当state不为0时进⼊AQS阻塞队列等待。
3. 其他线程调⽤countDown()时,state值原⼦性递减,当state值为0的时候,唤醒所有调⽤await()⽅
法阻塞的线程
我需要一些帮助来了解使用CountDownLatch相对于传统等待通知的优势。我认为notifyAll()确实做了同样的事情,而且似乎更容易使用(可能是因为熟悉)。另外,CountDownLatch的wait()和await()有什么区别?谢谢!编辑:我想我需要重新表述我的查询:Await()按照文档说:Causesthecurrentthreadtowaituntilthelatchhascounteddowntozero,unlessthethreadisinterrupted.对我来说,很难看出wait()和await()之间的区别-await()确实在幕后使用wait(),并且
我查看了代码,一切都是int--传递给CountDownLatch构造函数的参数是int,Sync中的变量是int,Sync.getCount()的返回类型是int。但是CountDownLatch.getCount()返回一个长?想知道为什么。 最佳答案 除非设计该API的人回答,否则我不知道您是否会找到该问题的充分答案,但它确实说它用于“调试和测试”。publiclonggetCount(){...}//justfordebuggingandtesting 关于java-为什么Cou
在docs对于CountDownLatch,我看到类似的内容:publicvoidrun(){try{startSignal.await();doWork();doneSignal.countDown();}catch(InterruptedExceptionex){}//return;}这里的startSignal和doneSignal是CountDownLatch对象。文档没有提及该类是否是线程安全的。 最佳答案 由于它被设计为由多个线程使用,因此可以公平地假设它是线程安全的线程安全的大多数含义。甚至还有一个happens-be
我看到一个stackoverflow成员建议使用Thread.join()让一个“主”线程等待2个“任务”线程完成。我会经常做一些不同的事情(如下所示),我想知道我的方法是否有任何问题。finalCountDownLatchlatch=newCountDownLatch(myItems.length);for(Itemitem:myItems){//doStufflaunchesaThreadthatcallslatch.countDown()asit'sfinalactitem.doStuff(latch);}latch.await();//ignoringExceptionsfor
我正在使用ExecutorService来实现一个3线程池,并使用CountDownLatch来监视所有线程的完成,以进行进一步处理。ExecutorServicethreadExecutor=Executors.newFixedThreadPool(3);CountDownLatchcountDownLatch=newCountDownLatch(3);AuthorisationHistoryTasktask1=newAuthorisationHistoryTask(commonDataThread,countDownLatch);PreAuthHistoryTasktask2=ne
我使用CountDownLatch等待来自另一个组件(在不同线程中运行)的特定事件。以下方法符合我的软件的语义,但我不确定它是否按我预期的那样工作:mCountDownLatch.await(3000,TimeUnit.MILLISECONDS)otherComponent.aStaticVolatileVariable=true;mCountDownLatch.await(3500,TimeUnit.MILLISECONDS);...场景应该是这样的:我等了3秒,如果latch没有倒数到0,我就用那个变量通知其他组件,然后我最多等3.5秒。如果再次超时,那我就不管了,继续进行其他操作
Java中的CyclicBarrier/CountDownLatch和join有什么区别?CyclicBarrier和CountDownLatch有什么优势?在我看来,只需使用join我们就可以等待线程完成其执行。 最佳答案 是的,“t.join()”使当前线程等待“t”线程完成,当一个线程正在等待其他线程时,我们可以准备一个线程链。但有时CountDownLatch/CyclicBarrier更方便。首先,CountDownLatch/CyclicBarrier不要求所有工作线程都应该完成。线程可以在应用程序运行时一直运行。他们只
我有多个消费者线程使用await()等待大小为1的CountDownLatch。我有一个生产者线程,它在成功完成时调用countDown()。这在没有错误的情况下效果很好。但是,如果生产者检测到错误,我希望它能够向消费者线程发出错误信号。理想情况下,我可以让生产者调用类似abortCountDown()的东西,并让所有消费者收到InterruptedException或其他一些异常。我不想调用countDown(),因为这需要我所有的消费者线程在调用await()之后再进行一次额外的手动检查是否成功。我宁愿他们只收到一个他们已经知道如何处理的异常。我知道CountDownLatch中没
当等待其他线程完成时,我们可以使用join或CountdownLatch。使用这两种机制的优缺点是什么? 最佳答案 如果您自己处理线程,则只能使用Thread.join。大多数人选择不直接处理线程处理的细节,而是使用ExecutorService为他们处理。ExecutorService不会直接显示它们是如何执行任务的,因此您必须使用CountDownLatch:(假设您不想只是shutdown整个服务,也就是。)ExecutorServiceservice=Executors.newFixedThreadPool(5);final
当等待其他线程完成时,我们可以使用join或CountdownLatch。使用这两种机制的优缺点是什么? 最佳答案 如果您自己处理线程,则只能使用Thread.join。大多数人选择不直接处理线程处理的细节,而是使用ExecutorService为他们处理。ExecutorService不会直接显示它们是如何执行任务的,因此您必须使用CountDownLatch:(假设您不想只是shutdown整个服务,也就是。)ExecutorServiceservice=Executors.newFixedThreadPool(5);final