CountDownLatch和CyclicBarrier的应用场景
程序员文章站
2022-07-14 23:49:59
...
模拟运动员100米赛跑的场景。我们定义两个CountDownLatch对象,初始化为5,分别代表起跑前5个运动员准备就绪,定义一个CountDownLatch对象,初始化为1,代表裁判鸣枪之后,大家才能一起跑,另外一个CountDownLatch代表五个运动员均达到终点,比赛才结束,效果如截图所示。
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
private static final int N = 5;
public static void main(String[] args) {
testCountDownLatch();
}
private static void testCountDownLatch() {
CountDownLatch latchStart = new CountDownLatch(N);
CountDownLatch latchOver = new CountDownLatch(N);
CountDownLatch startSignal = new CountDownLatch(1);
for (int i = 0; i < N; i++) {
new Thread(new Player(i, latchStart, latchOver, startSignal)).start();
}
System.out.println("等待运动员准备好");
try {
latchStart.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("开始比赛");
startSignal.countDown();
try {
latchOver.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有运动员都完成了比赛,比赛结束");
}
}
Player类的代码:
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Player implements Runnable {
private CountDownLatch latchStart;
private CountDownLatch latchOver;
private CountDownLatch startSignal;
private int id;
private static Random sRandom = new Random();
public Player(int id, CountDownLatch latchStart, CountDownLatch lacthOver, CountDownLatch startSignal) {
this.id = id;
this.latchStart = latchStart;
this.latchOver = lacthOver;
this.startSignal = startSignal;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(sRandom.nextInt(2));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Player" + id + "准备好" + System.currentTimeMillis());
this.latchStart.countDown();
try {
this.startSignal.await();
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("Player" + id + "开始跑" + System.currentTimeMillis());
long duration = sRandom.nextInt(5);
try {
TimeUnit.SECONDS.sleep(duration);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("Player" + id + "完成比赛, 耗时:" + duration);
this.latchOver.countDown();
}
}
我们定义两个CyclicBarrier对象,初始化为5,分别代表起跑前5个运动员准备就绪,因为CyclicBarrier是让所有线程达到同一个屏障,所以不像CountDownLatch里面要再统一起跑时间,另外一个CyclicBarrier代表五个运动员均达到终点,比赛才结束,效果如截图所示。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
private static final int N = 5;
public static final void main(String[] args) {
testCyclicBarrier();
}
private static void testCyclicBarrier() {
CyclicBarrier barrierPrepare = new CyclicBarrier(N, new Runnable() {
@Override
public void run() {
System.out.println("所有运动员准备完毕,开始比赛");
}
});
CyclicBarrier barrierOver = new CyclicBarrier(N, new Runnable() {
@Override
public void run() {
System.out.println("所有运动员比赛都完成了,结束比赛");
}
});
for (int i = 0; i < N; i++) {
new Thread(new Player(i, barrierPrepare, barrierOver)).start();
}
}
}
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
public class Player implements Runnable {
private CyclicBarrier barrierPrepared;
private CyclicBarrier barrierOver;
private int id;
private static Random sRandom = new Random();
public Player(int id, CyclicBarrier barrierPrepared, CyclicBarrier barrierOver) {
this.barrierPrepared = barrierPrepared;
this.barrierOver = barrierOver;
this.id = id;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(sRandom.nextInt(3));
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("运动员" + id + "准备比赛");
try {
barrierPrepared.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("远动员" + id + "开始比赛" + System.currentTimeMillis());
int duration = sRandom.nextInt(5);
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("运动员" + id + "完成比赛,比赛时长:" + duration);
try {
barrierOver.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
上一篇: 递归应用场景和调用机制
下一篇: RocketMQ双主双从异步复制集群搭建
推荐阅读
-
iOS应用UI开发中的字体和按钮控件使用指南
-
CURL的学习和应用(附多线程实现)
-
iOS应用设计模式开发中对简单工厂和工厂方法模式的运用
-
深入分析PayPal对Node.js的应用和开发案例
-
CorelDRAW样式和模板的应用
-
PHP explode()函数的几个应用和implode()函数有什么区别
-
AI“易容术”背后,人工智能技术应用场景拓展的攻擂与守擂
-
jupyter记事本的安装和简单应用
-
Java学习笔记(5)--- Number类和Math 类,String类的应用,Java数组入门
-
图论小结(一)包括一些最短路,最小生成树,差分约束,欧拉回路,的经典题和变种题。强连通,双连通,割点割桥的应用。二分匹配