Java并发编程-同步辅助类之CyclicBarrier

在上一篇文章中我们介绍了同步辅助类CountDownLatch,在Java concurrent包下还有另一个同步辅助类CyclicBarrier与CountDownLatch非常类似,它也允许多个线程在某个点进行同步,但CyclicBarrier类更加强大。

操作方法

  • 提供两种构造函数带Runnable的 CyclicBarrier(int parties, Runnable barrierAction)表示线程都同步后执行barrierAction。和不带Runnable。
  • await() 方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。

与CountDownLatch的不同之处

  • **CountDownLatch对象的作用只能使用一次,当计算减为0之后就不能再使用了。但CyclicBarrier对象可以重复使用。**在计算减为0后,如果再次调用await() 方法,计数就又会变成 N-1,新一轮重新开始,也可以通过reset()重置,这便是 Cyclic 的含义所在。

  • 不用向CountDownLatch一样调用countDown()方法

  • CyclicBarrier 的构造函数还可以接受一个 Runnable,会在所有得线程都到达同步点后执行某些操作。

  • CyclicBarrier.await() 方法会抛出一个独有的 BrokenBarrierException。这个异常发生在当某个线程在等待本 CyclicBarrier 时被中断或超时或被重置时,其它同样在这个 CyclicBarrier 上等待的线程便会受到 BrokenBarrierException。意思就是说,同志们,别等了,有个小伙伴已经挂了,咱们如果继续等有可能会一直等下去,所有各回各家吧

使用实例

该例子在CountDownLatch的例子上进行改进,使用CyclicBarrier类代替结束倒计锁,当CyclicBarrier对象的计算为0时,比赛结束,启动一个线程执行统计:

package MyThread;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;


public class Match {

	// 模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。
	public static void main(String[] args) throws InterruptedException {

		HashMap<String,String> result=new HashMap<>();
		// 开始的倒数锁 
		final CountDownLatch begin=new CountDownLatch(1) ;  
		// 结束的倒数锁  使用CyclicBarrier,在所有线程结束后启动统计线程
		final CyclicBarrier end=new CyclicBarrier(10, new Statistics(result));  
		
		// 十名选手 		
		for (int index = 0; index < 10; index++) {
			new Thread(new player(begin,end,result),"player"+index).start();
		}  
		System.out.println("Game Start");  
		// begin减一,开始游戏
		begin.countDown();  
		// 等待end变为0,即所有选手到达终点		

	}
}
class player implements Runnable{
	// 开始的倒数锁 
	private  final CountDownLatch begin ;  
	// 结束的倒数锁 
	private final CyclicBarrier end;  
	//成绩记录
	HashMap<String,String> result;

	player(CountDownLatch begin,CyclicBarrier end,HashMap<String,String> result){
		this.begin=begin;
		this.end=end;
		this.result=result;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {  
			// 如果当前计数为零,则此方法立即返回。
			// 等待
			begin.await();  
			Thread.sleep((long) (Math.random() * 10000));  
			result.put(Thread.currentThread().getName(), new Date().toString());
			System.out.println(Thread.currentThread().getName() + " arrived");  
			end.await();
		} catch (InterruptedException e) { 
			e.printStackTrace();          
		} catch (BrokenBarrierException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {  
			// 每个选手到达终点时,end就减一			
		}
	}
}
class Statistics implements Runnable{

	private HashMap<String,String> result;
	Statistics(HashMap<String,String> result){
		this.result=result;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("Game Over\nbegin statistics:");
		Iterator it=result.keySet().iterator();
		while(it.hasNext()){
			String key=(String)it.next();
			String value=result.get(key);
			System.out.println(key+":"+value);
		}
	}
	
}

结果
Game Start
player3 arrived
player4 arrived
player1 arrived
player6 arrived
player2 arrived
player0 arrived
player8 arrived
player7 arrived
player9 arrived
player5 arrived
Game Over
begin statistics:
player9:Mon Jun 06 21:15:26 CST 2016
player0:Mon Jun 06 21:15:22 CST 2016
player1:Mon Jun 06 21:15:20 CST 2016
player2:Mon Jun 06 21:15:22 CST 2016
player3:Mon Jun 06 21:15:17 CST 2016
player4:Mon Jun 06 21:15:18 CST 2016
player5:Mon Jun 06 21:15:27 CST 2016
player6:Mon Jun 06 21:15:21 CST 2016
player7:Mon Jun 06 21:15:25 CST 2016
player8:Mon Jun 06 21:15:22 CST 2016

其他同步辅助类:
Java并发编程-同步辅助类之Exchanger
Java并发编程-同步辅助类之Phaser
Java并发编程-同步辅助类之CountDownLatch
Java并发编程-同步辅助类之Semaphore

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值