CountDownLatch简介
Countdownlatch倒计时锁,用于线程间同步协作,让一个线程等待其他所有线程完成后在执行。
CountDownLatch简单使用举例
主线程等待线程1,2,3完成之后再执行:
java
public class Testcountdownlatch {
public static void main(String[] args) throws InterruptedException {
//创建CountDownLatch
CountDownLatch countDownLatch = new CountDownLatch(3);
System.out.println("主线程正在等待三个线程干活........");
new Thread(()->{
System.out.println("线程1开始干活...");
try {
sleep(1000);
} catch (InterruptedException e) { e.printStackTrace();}
System.out.println("线程1结束干活");
//完成任务,倒计时减一
countDownLatch.countDown();
}).start();
new Thread(()->{
System.out.println("线程2开始干活...");
try {
sleep(2000);
} catch (InterruptedException e) { e.printStackTrace();}
System.out.println("线程2结束干活");
//完成任务,倒计时减一
countDownLatch.countDown();
}).start();
new Thread(()->{
System.out.println("线程3开始干活...");
try {
sleep(3000);
} catch (InterruptedException e) { e.printStackTrace();}
System.out.println("线程3结束干活");
//完成任务,倒计时减一
countDownLatch.countDown();
}).start();
//主线程等待
countDownLatch.await();
System.out.println("主线程最终结束");
}
}
结合线程池使用:
java
public class countdownlatch {
public static void main(String[] args) {
//创建CountDownLatch
CountDownLatch countDownLatch = new CountDownLatch(3);
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(4);
//主线程
service.submit(()->{
System.out.println("主线程开始等待......");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有线程执行结束,主线程开始后续工作");
try {
sleep(2000);
} catch (InterruptedException e) { e.printStackTrace();}
System.out.println("工作:学习CountDownLatch很难吗?");
System.out.println("主线程也结束工作");
});
service.submit(()->{
System.out.println("线程1开始干活...");
try {
sleep(1000);
} catch (InterruptedException e) { e.printStackTrace();}
System.out.println("线程1结束干活");
countDownLatch.countDown();
});
service.submit(()->{
System.out.println("线程2开始干活...");
try {
sleep(2000);
} catch (InterruptedException e) { e.printStackTrace();}
System.out.println("线程2结束干活");
countDownLatch.countDown();
});
service.submit(()->{
System.out.println("线程3开始干活...");
try {
sleep(3000);
} catch (InterruptedException e) { e.printStackTrace();}
System.out.println("线程3结束干活");
countDownLatch.countDown();
});
//关闭线程池资源
service.shutdown();
}
}
CountDownLatch模拟王者荣耀加载流程
java
public class TimiLoad {
public static void main(String[] args) throws InterruptedException {
//创建线程池模拟玩家和游戏
ExecutorService service = Executors.newFixedThreadPool(7);
//创建6个玩家
CountDownLatch countDownLatch = new CountDownLatch(6);
//进度加载
String[] all = new String[6];
//游戏开始加载,主线程
service.submit(()->{
sleep(5000);
countDownLatch.await();
System.out.println("全部加载完成,准备进入战斗.....");
});
//召唤师
for (int i = 1; i <= 6; i++) {
int k=i;
service.submit(()->{
for (int j = 0; j <= 100; j++) {
Thread.sleep(50);
all[k-1] = "召唤师"+k+":"+j+"%";
System.out.print("\r" + Arrays.toString(all));
}
countDownLatch.countDown();
});
}
service.shutdown();
}
}
Cyclicbarrier简介
Cyclicbarrier是另外一种多线程并发控制工具,和CountDownLatch非常类似,它也可以实现线程间的计数等待,但它的功能比 CountDownLatch 更加复杂且强大。CyclicBarrier 可以理解为循环栅栏。只是比CountdownLatch多了一个循环使用的功能,即任务数等于0之后,再次调用await方法,计数就会回到最开始的值,重新执行。