CountDownLatch
倒计时器CountDownLatch
让主线程等待被join的线程执行完之后,主线程才能继续往下执行。
public class CountDownLatchDemo {
private static CountDownLatch start=new CountDownLatch(0);
private static CountDownLatch end =new CountDownLatch(10);
public static void main(String[] args) {
ExecutorService service= Executors.newFixedThreadPool(6);
System.out.println("开始准备");
for(int i=0;i<10;i++){
service.submit(()->{
System.out.println(Thread.currentThread().getName()+"运动员等待哨响"+ LocalDateTime.now());
try {
Thread.sleep(100);
start.await();
end.countDown();
System.out.println(Thread.currentThread().getName()+"运动员到达终点"+ LocalDateTime.now());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
说明
: 一个线程等待其他线程执行完之后再执行,相当于加强版的join,初始化CountDownLatch是需要设定计数器的数值(当计数器扣减至0时才可继续向下执行)
举例说明
:
比如在游戏开始时需要玩家全部准备完毕之后才开始,开始游戏可以理解为“主线程”,玩家准备理解为“其他线程”,在“其他线程”没有准备完毕之前,“主线程时等待状态”,当“其他线程”准备完毕之后“主线程”就会执行下一步开始游戏的动作。
CyclicBarrier
说明
让一组线程到达某个屏障,然后被阻塞,一直到最后一个线程到达屏障,然后屏障开放,所有被阻塞的线程继续执行,计数器与线程数相等。
public class CyclicBarrierDemo {
private static CyclicBarrier barrier = new CyclicBarrier(6, () -> {
System.out.println("运动员已全部进场");
});
public static void main(String[] args) {
System.out.println("运动员准备进场");
ExecutorService service = Executors.newFixedThreadPool(6);
for (int i = 0; i < 6; i++) {
service.submit(()->{
System.out.println("开始"+Thread.currentThread().getName());
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("结束"+Thread.currentThread().getName());
});
}
}
}
CountDownLatch 和 CyclicBarrier的区别
1.CountDownLatch 的计数器是大于或等于线程数的,而CyclicBarrier一定等于线程数
2.CountDownLatch 的放行由其他线程控制,而CyclicBarrier是由本身来控制的