Java并发编程-栅栏CyclicBarrier

    栅栏功能是阻塞一组线程直到某个事件的发生,当参与的线程达到栅栏位置的时候,将会调用await()方法,这将会阻塞当前线程直到所有的线程全部到达了栅栏。如果所有的线程都到达了栅栏,那么栅栏便会打开,此时所有的线程都会释放,而栅栏将被重置以便下次使用。

    CyclicBarrier有两个构造参数,如下。

CyclicBarrier(int parties) 
CyclicBarrier(int parties, Runnable barrierAction) 

    1.其中parities表示的是参与线程的个数,当前线程在调用await()方法的时候会进行阻塞,调用await()方法,计数器+1.当计数器等于parities的时候,栅栏便会放开。也就是执行到最后一个参与线程,此线程调用await()方法的时候,所有线程同时执行。

    2.barrierAction表示的是最后一个线程到达屏障时优先执行的任务。

    依旧拿比赛的事来说吧,例子是选手准备,然后释放栅栏,run()方法代码执行完表示运动员到达终点。还有例子就是不管开始,只有所有人都完成比赛,可以庆祝之类的。无非是任务的类Runner类里面的cyclicBarrier.await()位置的问题,选择CyclicBarrier的第二个构造器即可。

public class Runner implements Runnable{
	private CyclicBarrier cyclicBarrier;
	private int number;
	
	public Runner(CyclicBarrier cyclicBarrier, int number) {
		this.cyclicBarrier = cyclicBarrier;
		this.number = number;
	}

	public void run() {
		try {
			System.out.println(number+"th 就位");
			cyclicBarrier.await();
			System.out.println(number+"th 到达,耗时"+Math.random()*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}
}
public class Race {
	public static void main(String[] args) {
		final int count = 6;
		CyclicBarrier cyclicBarrier = new CyclicBarrier(count);
		for(int i = 1 ; i <= count ;i++){
			new Thread(new Runner(cyclicBarrier,i)).start();
		}
	}
}
2th 就位
5th 就位
3th 就位
4th 就位
6th 就位
1th 就位
2th 到达,耗时896.3213862018172
3th 到达,耗时571.0326287073248
4th 到达,耗时625.9050513357512
6th 到达,耗时300.6048271390146
1th 到达,耗时706.7176368903195
5th 到达,耗时235.70225351556374

    这个例子可以这么理解,CyclicBarrier中参与线程的数量是6,每当线程有调用barrier.await(),barrier中计数器便会+1,并且当前线程阻塞在barrier.await()这行代码处,当第6个线程调用barrier.await()方法的时候,计数器等于6,此时栅栏便会打开。所有线程中barrier.await()后面的代码便会得到执行。CyclicBarrier(int parties),参与线程的数量是parties,但调用barrier.await()的线程小于parties,即栅栏计数器小于parties,那么所有线程会一直等待下去,得不到执行。

    CyclicBarrier有Runnable参数的构造器CyclicBarrier(int parties, Runnable barrierAction),线程通过栅栏时,Runnable对象会被优先执行,然后所有线程barrier.await()后面的代码得到执行。

例如:100米的比赛,所有参赛选手都到终点情况下,比赛结束,否则比赛还在进行中。    

public class Runner implements Runnable{

	private CyclicBarrier cyclicBarrier;
	private int number;
	
	public Runner(CyclicBarrier cyclicBarrier, int number) {
		this.cyclicBarrier = cyclicBarrier;
		this.number = number;
	}

	public void run() {
		try {
			System.out.println(number+"th 开跑!");
			Thread.sleep(1000);
			System.out.println(number+"th 到达!");
			cyclicBarrier.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}
}
public class Race {
	public static void main(String[] args) {
		final int count = 6;
		CyclicBarrier cyclicBarrier = new CyclicBarrier(count,new Runnable(){
			public void run(){
				System.out.println("所有人到达终点,该比赛结束了");
			}
		});
		for(int i = 1 ; i <= count ;i++){
			new Thread(new Runner(cyclicBarrier,i)).start();
		}
	}
}
1th 起跑!
3th 起跑!
5th 起跑!
2th 起跑!
4th 起跑!
6th 起跑!
1th 到达!
5th 到达!
3th 到达!
6th 到达!
4th 到达!
2th 到达!
该比赛结束了

第二个例子将cyclicBarrier.await()方法放在Runner的最后,相当于是最后一个线程执行到这里的时候,此时栅栏释放。所有的线程继续执行。
    思想引入自《Java并发编程实战》。




 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值