CountDownLatch介绍
去其他地方看吧
CountDownLatch常用接口:
-
构造函数创建CountDownLatch对象:
CountDownLatch countDownLatch = new CountDownLatch(num);
输入初始倒计时开始数据,也是需要执行的任务数量
-
countDown() : 多线程中使用,线程任务结束时执行,num--,表示一个线程任务的结束。
-
await() : 阻塞主线程,等待多个线程任务执行完成,再继续后续的操作。
常见业务场景
- 一等多:主线任务等待多个支线任务执行完成再走流程。比如:人满发车(每个座位是支线任务,发车是主线任务)
- 多等一:多个任务等待主线任务完成再开始执行。比如:长跑比赛,枪响开跑,跑完比赛结束。
CountDownLatch对于多线程的实现
CountDownLatch本身是单线程的,如果要进行多线程操作,需要搭配线程池
代码实现
package CountDownLatchDemo;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
OneWaitMore();
MoreWaitOne();
}
/**
* 场景:一个等多个
* 比如:人满发车
*/
private static void OneWaitMore() {
int seatCount = 20; // 座位数量
// 设置计时器倒计时座位剩余的数量
CountDownLatch countDownLatch = new CountDownLatch(seatCount);
// 创建线程池,实现多线程执行
int cpuCount = Runtime.getRuntime().availableProcessors();
ExecutorService executorService = Executors.newFixedThreadPool(cpuCount * 2 + 1);
for (int i = 0; i < seatCount; i++) {
int tmp = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("座位" + tmp + "已经被占");
} catch (InterruptedException e) {
System.out.println("座位出现异常,无法落座");
}finally {
countDownLatch.countDown();
}
}
});
}
// 所有座位被占满之前,等待
try {
countDownLatch.await();
} catch (InterruptedException e) {
System.out.println("等待过程出现异常");
}
if (countDownLatch.getCount() == 0) {
System.out.println("车已做满,开始发车");
}else {
System.out.println("不会走到这里的。。。");
}
}
/**
* 场景:多等一
* 比如:长跑比赛,枪响开跑,跑完比赛结束。
*/
private static void MoreWaitOne() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
int athleteCount = 10; // 参加比赛的远动员数量
CountDownLatch athletes = new CountDownLatch(athleteCount);
// 运动员准备过程:创建多个线程
for (int i = 0; i < athleteCount; i++) {
int tmp = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
startSignal.await(); // 等待枪响的信号
Thread.sleep(10); // 完成跑程的时长
System.out.println(tmp+"号运动员到达终点");
athletes.countDown();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
}
Thread.sleep(3);
System.out.println("比赛倒计时 : 1");
Thread.sleep(3);
System.out.println("比赛倒计时 : 2");
Thread.sleep(3);
System.out.println("比赛倒计时 : 3");
startSignal.countDown();
System.out.println("比赛开始");
athletes.await();
System.out.println("比赛结束");
}
}
代码执行接口: