同步器CyclicBarrier

接着说另外一个同步器CyclicBarrier,在jdk的文档中是这么描述的:“一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点(common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。 ”,同时在描述CountDownLatch中也说道“用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用CyclicBarrier",这就给出了两者之间的关系,CyclicBarrier 是CountDownLatch的一个扩展。

上篇文章举了赛跑的例子,选手跑完之后颁奖则不再有后续的活动,假如说以下这个例子,场景:有几个人通过不同的路线做宣传活动,第一站要先到北京,在北京集结(都要到达)之后再以不同的路线前往杭州,而在杭州也要集结,然后同时以不同的路现前往广州。 如果是这么一种情况CountDownLatch则无能为力了,下面的代码是使用CyclicBarrier 来实现的:

package com.test.concurrent.cyclicBarrier;

import java.util.concurrent.CyclicBarrier;

import com.test.util.AppRandom;
import com.test.util.SleepUtil;

public class CyclicBarrierDemo {

	public static CyclicBarrier getFirstCyclicBarrier(int count) {
		if (count <= 0)
			return null;
		final CyclicBarrier cyclicBarrier = new CyclicBarrier(count,
				new Runnable() {
					public void run() {
						SleepUtil.sleep(100);
						System.out.println("》》》》》》所有人员都已经到达北京》》》》》》》》开始下一步行动:目的地杭州");
					}
				});
		return cyclicBarrier;
	}
	
	public static CyclicBarrier getSecondCyclicBarrier(int count) {
		if (count <= 0)
			return null;
		final CyclicBarrier cyclicBarrier = new CyclicBarrier(count,
				new Runnable() {
					public void run() {
						SleepUtil.sleep(100);
						System.out.println("》》》》》》所有人员都已经到达杭州》》》》》》》》开始下一步行动:目的地广州");
					}
				});
		return cyclicBarrier;
	}

	public static Thread getThread(String nameOfThread,
			final CyclicBarrier cyclicBarrier1,final CyclicBarrier cyclicBarrier2) {
		Thread thread = new Thread(nameOfThread) {
			public void run() {
				SleepUtil.sleep(AppRandom.getNumber(4));
				System.out.println(this.getName() + " 到达北京; 序号: " + (++count));
				try {
					cyclicBarrier1.await();
					SleepUtil.sleep(AppRandom.getNumber(4));
					System.out.println(this.getName() + " 到达杭州; 序号: " + (++count));
					cyclicBarrier2.await();
				} catch (Exception e) {
					e.printStackTrace();
				}
//				System.out.println(this.getName() + " 开始前往广州");
			}
		};
		return thread;

	}

	static int count = 0;

	public static void main(String[] args) {
		CyclicBarrier cyclicBarrier1 = getFirstCyclicBarrier(3);
		CyclicBarrier cyclicBarrier2 = getSecondCyclicBarrier(3);
		Thread threadOne = getThread("路人甲", cyclicBarrier1, cyclicBarrier2);
		threadOne.start();
		Thread threadTwo = getThread("路人乙", cyclicBarrier1, cyclicBarrier2);
		threadTwo.start();
		Thread threadThree = getThread("路人丙", cyclicBarrier1, cyclicBarrier2);
		threadThree.start();
	}
}

这个片段可以运行,运行结果是(线程完成的顺序未必一致,但是中间的集结状态肯定是一致的):

路人丙 到达北京; 序号: 1
路人乙 到达北京; 序号: 2
路人甲 到达北京; 序号: 3
》》》》》》所有人员都已经到达北京》》》》》》》》开始下一步行动:目的地杭州
路人乙 到达杭州; 序号: 4
路人丙 到达杭州; 序号: 5
路人甲 到达杭州; 序号: 6
》》》》》》所有人员都已经到达杭州》》》》》》》》开始下一步行动:目的地广州


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值