进阶篇:线程并行与等待之CyclicBarrier(十三)

考虑这样一个场景,假设你有多个线程,这些线程并行执行,你设置了一个目的地,你想做到的是,无论哪个线程先到达目的地,都得等待其它线程到达,当指定数量的线程都到达目的地时,才允许它们继续一起往下执行;


这个时候就是CyclicBarrier的用武之地了!

	//一组任务并行执行,这些任务之间互相等待,直到指定的线程数都到达某一个屏障点(就是调用await的地方) ,才允许往下执行
	//就像是一堆马,无论它们谁先打到围栏处,都得先等待其它马到达,当全部到达后,再打开围栏,允许它们继续行走;
	//CyclicBarrier与CountDownLatch不同的是,它可以一直循环下去,下面需要等待3个线程执行完毕,当3个线程执行完毕后,它放行一次,接着自动重新等待3个线程...
	
	//构造函数中可以传入一个线程,也可以不传,当屏障被打开时,该线程将先获得调用!
	public static void cyclicBarrier() throws InterruptedException, BrokenBarrierException{
		final CyclicBarrier cb = new CyclicBarrier(3,new Runnable() {
			public void run() {
				//当屏障被打开时,该线程将先获得调用!
				System.out.println("屏障点被打开!");
			}
		});
		ExecutorService exec =Executors.newCachedThreadPool();
		for (int i = 0; i < 6; i++) {
			exec.execute(new Runnable() {
				public void run() {
					try {
						System.out.println("准备执行一次任务");
						TimeUnit.MILLISECONDS.sleep(new Random().nextInt(2000));
						System.out.println("等待其他任务执行");
						//屏障点,当到达屏障点的线程数量满足CyclicBarrier的初始化数量,屏障将打开,然后继续等待,
						//在我们这六个线程中,当有3个线程调用了cb.await()时,屏障打开,3个线程放行;而后3个线程需要继续等待屏障打开
						cb.await();
						System.out.println("任务执行完毕");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		}
		
		exec.shutdown();
	}



看一下输出:*************************************************************************************

准备执行一次任务
准备执行一次任务
准备执行一次任务
准备执行一次任务
准备执行一次任务
准备执行一次任务
等待其他任务执行
等待其他任务执行
等待其他任务执行
屏障点被打开!
任务执行完毕
任务执行完毕
任务执行完毕
等待其他任务执行
等待其他任务执行
等待其他任务执行
屏障点被打开!
任务执行完毕
任务执行完毕
任务执行完毕

***************************************************************************************************

我们创建了一个CyclicBarrier,构造参数3代表着它每次等待的线程数是3个,另一个构造参数则是当有3个线程执行到达屏障点时,它将获得执行;


从输出中我们看到,先是6个线程都打印出【准备执行一次任务】,然后它们被sleep阻塞,首先是3个线程到屏障点,然后屏障被打开,另外3个线程才得以执行,且这三个线程到达屏障点时又一次打印出了【屏障点被打开!】,说明CyclicBarrier是可以一直循环复用下去的;


CyclicBarrier还有些方法可以用,比如在运行时改变要等待的线程数,这个在CountDownLatch是不能改变的;具体参见API;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值