关闭

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

390人阅读 评论(0) 收藏 举报

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()
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			/**参会员工去会议室*/
			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()
	 */
	@Override
	public 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();
		}
	}
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4256次
    • 积分:85
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:6篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档