您的位置:首页 > 编程语言 > Java开发

Java并发之CyclicBarrier的学习

2018-03-05 10:55 369 查看
CyclicBarrier,是JDK1.5加入的新特性。适用场景举例如下:

在百米赛跑中,只有在运动员准备好之后才开始。假设每个线程代表一个运动员,它会去等待其他运动员准备好(体现在await方法),只有当所有的运动员准备好后才能开始;

你希望创建一组任务,它们并发地执行工作,另外的一个任务在这一组任务并发执行结束前一直阻塞等待,直到该组任务全部执行结束,这个任务才得以执行(如颁奖是在赛跑之后进行)
常用API方法解析:
CyclicBarrier(int parties)

          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)

          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。
其中,parties相当于参加赛跑中运动员的数量;构造方法2对应场景2
代码展示如下:public class CyclicBarrierDemo {
public static void main(String[] args) {
final CyclicBarrier barrier = new CyclicBarrier(4);
ExecutorService executorService = Executors.newFixedThreadPool(4);
CyclicBarrierDemo cyclicBarrierDemo = new CyclicBarrierDemo();
executorService.execute(cyclicBarrierDemo.new CyclicBarrierTest(barrier, "1"));
executorService.execute(cyclicBarrierDemo.new CyclicBarrierTest(barrier, "2"));
executorService.execute(cyclicBarrierDemo.new CyclicBarrierTest(barrier, "3"));
executorService.execute(new Runnable() {

@Override
public void run() {
try {
System.out.println("线程4准备");
Thread.sleep(1000);
barrier.await(2, TimeUnit.SECONDS);
System.out.println("线程4 准备好了");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}

}
});
executorService.shutdown();
}

private class CyclicBarrierTest implements Runnable {
private CyclicBarrier barrier;
private String name;

public CyclicBarrierTest(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
}

@Override
public void run() {
try {
System.out.println("线程" + name + "准备 ");
Thread.sleep(2000);
barrier.await(2, TimeUnit.SECONDS);
System.out.println("线程" + name + " 准备好了");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}

}
}运行情况:线程1准备
线程3准备
线程2准备
线程4准备
线程3 准备好了
线程4 准备好了
线程2 准备好了
线程1 准备好了针对场景2的代码展示:public class CyclicBarrierDemo2 {
public static void main(String[] args) {
final CyclicBarrier barrier = new CyclicBarrier(3,new Runnable() {

@Override
public void run() {
System.out.println("--------------------------");
System.out.println("运动员赛跑结束,下面开始颁奖");

}
});
ExecutorService executorService = Executors.newFixedThreadPool(4);
CyclicBarrierDemo2 cyclicBarrierDemo = new CyclicBarrierDemo2();
executorService.execute(cyclicBarrierDemo.new CyclicBarrierTest(barrier, "1"));
executorService.execute(cyclicBarrierDemo.new CyclicBarrierTest(barrier, "2"));
executorService.execute(cyclicBarrierDemo.new CyclicBarrierTest(barrier, "3"));
executorService.shutdown();
}

private class CyclicBarrierTest implements Runnable {
private CyclicBarrier barrier;
private String name;

public CyclicBarrierTest(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
}

@Override
public void run() {
try {
System.out.println("运动员" + name + "准备 ");
Thread.sleep(2000);
System.out.println("运动员" + name + " 跑过终点");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}

}
}运行情况:运动员1准备
运动员3准备
运动员2准备
运动员3 跑过终点
运动员1 跑过终点
运动员2 跑过终点
--------------------------
运动员赛跑结束,下面开始颁奖
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 并发 同步