通过三个示例说明CyclicBarrier的使用。
示例一
赛跑时,等待所有人都准备好时才起跑:
package com.xs.concurrent;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
// 如果将参数改为4,但是下面只加入了3个选手,这永远等待下去
CyclicBarrier barrier = new CyclicBarrier(3);
for (int i = 0; i < 3; i++) {
new Thread(new Runner(barrier, (i + 1) + "号选手")).start();
}
}
}
class Runner implements Runnable{
// 公共屏障点 (common barrier point)
private CyclicBarrier barrier;
private String name;
public Runner(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000 * new Random().nextInt(5));
System.out.println(name + "已经准备好了!");
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(name + "起跑了!");
}
}
运行结果:
3号选手已经准备好了!
1号选手已经准备好了!
2号选手已经准备好了!
2号选手起跑了!
1号选手起跑了!
3号选手起跑了!
示例二
统计GDP,先开启多个线程统计各省GDP,然后再综合统计全国GDP:
package com.xs.concurrent;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest2 {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(5, new TotalTask());
new Thread(new StateTask(barrier, "湖南")).start();
new Thread(new StateTask(barrier, "广东")).start();
new Thread(new StateTask(barrier, "北京")).start();
new Thread(new StateTask(barrier, "上海")).start();
new Thread(new StateTask(barrier, "重庆")).start();
}
}
class TotalTask implements Runnable{
@Override
public void run() {
System.out.println("统计全国GDP!");
}
}
class StateTask implements Runnable{
private CyclicBarrier barrier;
private String name;
public StateTask(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000 * new Random().nextInt(5));
System.out.println(name + "GDP统计完毕!");
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
运行结果:
湖南GDP统计完毕!
广东GDP统计完毕!
重庆GDP统计完毕!
上海GDP统计完毕!
北京GDP统计完毕!
统计全国GDP!
示例三
下面这个示例用来说明CyclicBarrier使参与方反复地在栅栏位置汇集:
package com.xs.concurrent;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierTest3 {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
String[] names = {"爱因斯坦", "牛顿", "罗素", "高斯"};
final CyclicBarrier barrier = new CyclicBarrier(names.length); // 四个人同时到达
for (String name : names) {
service.execute(new Member(barrier, name, names.length));
}
service.shutdown();
}
}
class Member implements Runnable{
private CyclicBarrier barrier;
private String name;
private int totalMember;
public Member(CyclicBarrier barrier, String name, int totalMember) {
this.barrier = barrier;
this.name = name;
this.totalMember = totalMember;
}
@Override
public void run() {
try {
// 公司集合
Thread.sleep(1000 * new Random().nextInt(5));
System.out.println(name + "到了公司!");
if (barrier.getNumberWaiting() == totalMember - 1) {
System.out.println("所有人员已到达公司,准备去聚餐...");
}
barrier.await();
// 聚餐
Thread.sleep(1000 * new Random().nextInt(5));
System.out.println(name + "到了聚餐地点!");
if (barrier.getNumberWaiting() == totalMember - 1) {
System.out.println("所有人员已到达聚餐地点,准备吃饭...");
}
barrier.await();
// K歌
Thread.sleep(1000 * new Random().nextInt(5));
System.out.println(name + "到了K歌地点!");
if (barrier.getNumberWaiting() == totalMember - 1) {
System.out.println("所有人员已到达K歌地点,一起嗨起来!");
}
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
运行结果:
牛顿到了公司!
爱因斯坦到了公司!
罗素到了公司!
高斯到了公司!
所有人员已到达公司,准备去聚餐...
罗素到了聚餐地点!
牛顿到了聚餐地点!
爱因斯坦到了聚餐地点!
高斯到了聚餐地点!
所有人员已到达聚餐地点,准备吃饭...
爱因斯坦到了K歌地点!
罗素到了K歌地点!
牛顿到了K歌地点!
高斯到了K歌地点!
所有人员已到达K歌地点,一起嗨起来!