java - CountdownLatch 演示程序。不等待 coutdown 锁存器结束
问题描述
在这个程序中,为什么 All countdownlatch over message 打印在两者之间。虽然它应该等待所有倒计时锁存器结束。因为在 main 方法中启动了一个额外的线程,但应该作为调用 cdl.countDown() 方法来处理处理此线程的倒计时。为什么它违反倒计时锁存器?
import java.util.concurrent.CountDownLatch;
public class CDLDemo implements Runnable {
static int count = 0;
CountDownLatch cdl = new CountDownLatch(5);
void checkForAwait() {
cdl.countDown();
System.out.println("Start " + cdl.getCount());
CDLTask1 cdlTask1 = new CDLTask1(cdl);
CDLTask2 cdlTask2 = new CDLTask2(cdl);
CDLTask3 cdlTask3 = new CDLTask3(cdl);
CDLTask4 cdlTask4 = new CDLTask4(cdl);
Thread t1 = new Thread(cdlTask1);
Thread t2 = new Thread(cdlTask2);
Thread t3 = new Thread(cdlTask3);
Thread t4 = new Thread(cdlTask4);
t1.start();
t2.start();
t3.start();
t4.start();
try {
cdl.await();
System.out.println("All countdownlatch over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
checkForAwait();
}
public static void main(String[] args) throws InterruptedException {
CDLDemo cdlDemo = new CDLDemo();
Thread t1 = new Thread(cdlDemo, "Thread1");
t1.start();
t1.join();
System.out.println("All completed");
}
static int getCount() {
return count++;
}
static class CDLTask1 implements Runnable {
CountDownLatch cdl;
public CDLTask1(CountDownLatch cdl) {
this.cdl = cdl;
}
@Override
public void run() {
getCount();
cdl.countDown();
System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
}
}
static class CDLTask2 implements Runnable {
CountDownLatch cdl;
public CDLTask2(CountDownLatch cdl) {
this.cdl = cdl;
}
@Override
public void run() {
cdl.countDown();
System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
}
}
static class CDLTask3 implements Runnable {
CountDownLatch cdl;
public CDLTask3(CountDownLatch cdl) {
this.cdl = cdl;
}
@Override
public void run() {
cdl.countDown();
System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
}
}
static class CDLTask4 implements Runnable {
CountDownLatch cdl;
public CDLTask4(CountDownLatch cdl) {
this.cdl = cdl;
}
@Override
public void run() {
cdl.countDown();
System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
}
}
}
解决方案
您在 CDLTask 中的打印语句是在cdl.countDown()
那之后为什么您会在两者之间得到消息的原因。该线程可能在倒计时和打印语句之间被抢占,然后您的 main 可能会在所有打印完成之前发出信号。
推荐阅读
- javascript - 未处理的拒绝错误:ETELEGRAM:400 错误请求:消息文本为空
- azure - Javascript blobtrigger 示例函数因 StorageException 而崩溃
- sql-server - 根据第一个查询的结果从第二个数据库获取数据
- java - 如何在 Spring Boot 项目中模拟 .properties 文件
- jsf - 执行 ManagedBean 方法的调用并将其结果放入 fn:replace 函数应该有什么语法?
- idl-programming-language - 使用 acre.pro 例程时出错:“程序无法从单语句模式编译”
- amazon-web-services - 在 AWS 负载平衡环境中使用经典 ASP 会话变量是否有技巧?
- html - 对齐左表上的图像?
- ios - 应用程序上的图像太小,而且有很多空白单元格,我怎样才能让我的图像变大,以便它可以容纳我手机屏幕的一半?
- python - 如何解析特定的 cookie 值?