并发线程库中并发辅助类CyclicBarrier使用详解

来源:互联网 发布:rap 说唱教学软件 编辑:程序博客网 时间:2024/05/22 00:16

ClyClicBarrier是线程并发库中的一个并发辅助类,允许一组线程相互等待,直到所有的线程都到达屏障点才被CyclicBarrier释放唤醒。释放等待线程后的CyclicBarrir可以重用,因此我们将其称之为循环的barrier。

CyclicBarrier对象的创建:

1、new CyclicBarrier(int parties):

创建具有指定数量参与者(线程)的CyclicBarrier,当所有的参与者(线程)都处于等待状态时启动屏障,但不会在启动屏障的时候执行预定义的屏障操作。

2、new CyclicBarrier(int parties, Runnable run):

创建具有指定数量参与者(线程)的CyclicBarrier,当所有的参与者(线程)都处于等待状态时启动屏障,并在启动屏障的时候执行预定义的屏障操作,预定义屏障操作是由run参数指定的,由最后一个进入等待状态的参与者(线程)执行。

CyclicBarrier中的重要方法:

int await():

在所有的参与者(线程 )中都调用了barrier的await方法之前,导致调用barrier.await方法的当前线程一直等待;即要使参与者(线程)到达 屏障点,必须在参与者(线程)中调用barrier的await方法。该方法是个阻塞方法。

CyclicBarrier的执行过程:

1、在所有的参与者(线程)中调用barrier的await方法,使当前线程到达屏障点进入等待状态。

2、CyclicBarrier在所有指定数量的参与者都进入屏障点(调用barrier的await方法)之前一直处于等待状态,等待所有的参与者(线程)都到达屏障点。

3、当指定数量的参与者(线程)都调用了barrier.await方法到达屏障点后,barrier启动屏障;如果预定义了屏障操作,则由最后一个到达屏障点的参与者(线程)执行屏障操作,也就是执行run线程。

4、参与者(线程)自调用barrier的await方法起就一直处于等待状态,当屏障操作执行完毕后,barrier会释放等待线程(参与者),并唤醒参与者,参与者(线程)又可以做自己的事情,而barrier又回到初始状态,可以被重新使用。


下面使用CyclicBarrier模拟公司员工开会的场景:

1、员工进入会议室。

2、等所有的参会员工都到达会议室后才开始会议。

3、员工在会议期间发表讲话。

/** *  */package com.huaxia.concurrent.cyclicbarrier;import java.util.Random;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * @author wangcz * CyclicBarrier测试入口类 * 模拟场景:公司员工开会,等全部员工都到齐后才开始会议 */public class CyclicBarrierTestMain {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub/**假定公司参加会议的人数为20*/CyclicBarrier cb = new CyclicBarrier(20, new BarrierThread());Random ran = new Random();ExecutorService es = Executors.newCachedThreadPool();for (int i = 1; i <= 20; i++) {es.submit(new EmployeeJoinMeeting(cb, ran.nextInt(900) + 100));}es.shutdown();}}


/** *  */package com.huaxia.concurrent.cyclicbarrier;import java.util.concurrent.CyclicBarrier;/** * @author wangcz * 前来参加会议的员工类 */public class EmployeeJoinMeeting implements Runnable {private CyclicBarrier cb;private long useTime;/** * @param cb * @param useTime */public EmployeeJoinMeeting(CyclicBarrier cb, long useTime) {super();this.cb = cb;this.useTime = useTime;}/** *  */public EmployeeJoinMeeting() {super();}/* (non-Javadoc) * @see java.lang.Runnable#run() */@Overridepublic void run() {// TODO Auto-generated method stubtry {/**参会员工去会议室*/System.out.println("[" + Thread.currentThread().getName() + "] is walking to meet...");Thread.sleep(useTime);System.out.println("[" + Thread.currentThread().getName() + "] uses time " + useTime + "ms, now has reached meetingroom...");/**等待所有参会员工到齐*/cb.await();/**参会员工发表讲话*/System.out.println("[" + Thread.currentThread().getName() + "] has speaked in meetingroom...");} catch (Exception e) {e.printStackTrace();}}}

/** *  */package com.huaxia.concurrent.cyclicbarrier;/** * @author wnagcz * 屏障操作线程,当最后一个线程到达屏障点,该线程执行 */public class BarrierThread implements Runnable {/* (non-Javadoc) * @see java.lang.Runnable#run() */@Overridepublic void run() {System.out.println("all employees has reached, now the meeting is going to begin...");try {Thread.sleep(5000);} catch (Exception e) {e.printStackTrace();}}}


原创粉丝点击