CountDownLatch
倒计时锁存器 用来解决线程执行次序的问题
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞。
其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),
当计数器的值变为o时,因await方法阻塞的线程会被唤醒,继续执行。
下面例子中,主线程‘班长’需要等子线程全部执行完成再执行,但是出现了如下情况:
运行结果:
代码:
public class CountDownLatchDemo {
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println("离开了教室");
},i+"").start();
}
System.out.println("班长关门走人");
}
}
解决方法:使用CountDownLatch
运行结果:
代码:
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println("离开了教室");
countDownLatch.countDown();
},i+"").start();
}
countDownLatch.await();
System.out.println("班长关门走人");
}
}
CyclicBarrier
---------------------(循环屏障)
和上面的CountDownLatch(做减法倒计时开始任务)不同,CyclicBarrier是做加法来开始任务的
运行结果:
代码:
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, ()->{
System.out.println("召唤神龙");
});
for (int i = 0; i < 7; i++) {
int temp = i;
new Thread(()->{
try {
System.out.println("集齐第"+temp+"颗龙珠");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},i+"").start();
}
}
}