一、概述
CountDownLatch可以使得当前线程阻塞,直到当CountDownLatch中的计数器减少至0,当前线程才能继续往下执行.与Thread中的join()方法类似。
二、常用方法
- CountDownLatch(int count):指定计数器的值
- public void await() throws InterruptedException:调用后当前线程阻塞,直到当计数器的值为0,方法返回,该方法可以响应中断
- public boolean await(long timeout, TimeUnit unit) throws InterruptedException:可以超时时间等待,如果在规定的时间内返回,就返回ture。否则返回false
- public void countDown():让计数器减1
三、案例
简单使用
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
int count = 5;
CountDownLatch countDownLatch = new CountDownLatch(count);
for (int i=1;i<=count;i++){
Thread thread = new Thread(()->{
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+"到达终点");
countDownLatch.countDown();
}
});
thread.setName("线程"+i);
thread.start();
}
System.out.println("main线程被阻塞,需要等待其他所有线程到达终点,才能继续往下执行");
countDownLatch.await();
System.out.println("main线程继续执行,执行结束");
}
}
执行效果:
main线程被阻塞,需要等待其他所有线程到达终点,才能继续往下执行
线程1到达终点
线程2到达终点
线程3到达终点
线程4到达终点
线程5到达终点
main线程继续执行,执行结束
超时时间等待
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
int count = 5;
CountDownLatch countDownLatch = new CountDownLatch(count);
for (int i=1;i<=count;i++){
Thread thread = new Thread(()->{
try {
int time = (int)(Math.random()*10+1);
TimeUnit.SECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+"到达终点");
countDownLatch.countDown();
}
});
thread.setName("线程"+i);
thread.start();
}
System.out.println("main线程被阻塞,等待5秒其他线程到达终点");
boolean flag = countDownLatch.await(6,TimeUnit.SECONDS);
if (flag){
System.out.println("main线程等待其他线程到达才结束");
}else {
System.out.println("mian线程等不及了,自己往下执行结束");
}
}
}
执行结果:
main线程被阻塞,等待5秒其他线程到达终点
线程5到达终点
线程4到达终点
mian线程等不及了,自己往下执行结束