/**
* CountDownLatch的两种使用场景:
* 场景1:让多个线程等待
* 场景2:和让单个线程等待。
*/
public class CountDownLatchDemo {
public static void main(String[] args) {
// changjing1();
changjing2();
}
//场景1:让多个线程等待
/**
* >(1)在这个场景中,CountDownLatch充当的是一个发令枪的角色;
* 就像田径赛跑时,运动员会在起跑线做准备动作,等到发令枪一声响,运动员就会奋力奔跑。
*
* >(2)我们通过CountDownLatch.await(),让多个参与者线程启动后阻塞等待,
* 然后在主线程 调用CountDownLatch.countdown(1) 将计数减为0,
* 让所有线程一起往下执行;以此实现了多个线程在同一时刻并发执行,来模拟并发请求的目的。
*/
public static void changjing1() {
CountDownLatch countDownLatch = new CountDownLatch(1);
for (int i = 0; i < 5; i++) {
final int index = i;
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "\t运动员" + index + "号\t准备");
////准备完毕……运动员都阻塞在这,等待号令
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "\t运动员" + index + "号\t开跑");
} catch (InterruptedException e) {
}
},"线程" + i).start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
countDownLatch.countDown();
}
//场景2:和让单个线程等待。
//5个人都下班,才算真正的下班
public static void changjing2() {
CountDownLatch countDownLatch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
final int index = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName() + " --> 员工" + index + "号\t收拾东西下班");
try {
Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
},"线程" + i).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
}
System.out.println("所有人都走了,可以下班了,嘿嘿^_^");
}
}
线程0 运动员0号 准备
线程4 运动员4号 准备
线程3 运动员3号 准备
线程1 运动员1号 准备
线程2 运动员2号 准备
线程0 运动员0号 开跑
线程1 运动员1号 开跑
线程3 运动员3号 开跑
线程4 运动员4号 开跑
线程2 运动员2号 开跑
线程1 --> 员工1号 收拾东西下班
线程3 --> 员工3号 收拾东西下班
线程4 --> 员工4号 收拾东西下班
线程2 --> 员工2号 收拾东西下班
线程0 --> 员工0号 收拾东西下班
所有人都走了,可以下班了,嘿嘿^_^