释义:
CountDownLatch 也就是倒计锁,常用来阻塞主线程、等待被子线程唤醒,或者在子线程中阻塞等待被主线程唤醒
常用方法:
1、countDown()
countDown() 方法是用来执行线程计数器-1的,也就是多线程运行完之后,都调用此方法将计数器变成0,最后调用await()方法唤醒阻塞的位置,继续执行
2、await()
await() 方法是用来阻塞线程的,等待倒计锁被减到0的时候,才会唤醒该方法继续执行。也可以设置等待超时时间,如 countDownLatch.await(30, TimeUnit.SECONDS),设置超时时间则需要判断等待结果,true等待未超时、false等待已超时
3、 使用示例
代码:
//等待方式一、正常阻塞
int threadCount = 3;
CountDownLatch countDownLatch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
executorService.execute(() -> {
System.out.println("子线程" + Thread.currentThread().getName() + "执行!");
countDownLatch.countDown();
});
}
try {
//阻塞主线程,等待 countDownLatch 减到0,然后被唤醒
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程执行完毕!");
//等待方式二、设置限时阻塞
int threadCount = 3;
CountDownLatch countDownLatch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
System.out.println("子线程" + Thread.currentThread().getName() + "执行!");
countDownLatch.countDown();
});
}
try {
//阻塞主线程,等待 countDownLatch 减到0,然后被唤醒
boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
if (!await) {
System.out.println("子线程执行需要3秒,阻塞只等待2秒,等待超时!");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程执行完毕!");
分别输出:
总结:
1、countDown() 是用来执行倒计锁 -1
2、await() 用来阻塞线程,直至 countDown() 把倒计锁减到 0 才会被唤醒
3、await() 可以设置阻塞超时等待时间,需要判断等待结果 boolean 值。如果不设置超时时间则会一直等待,不需要判断返回值