Java并发库(十五):线程等待CyclicBarrier

深切怀念传智播客张孝祥老师,特将其代表作——Java并发库视频研读两遍,受益颇丰,记以后阅

15.java5CyclicBarrier同步工具

       例如:组织人员(线程)郊游,约定一个时间地点(路障),人员陆续到达地点,等所有人员全部到达,开始到公园各玩各的,再到约定时间去食堂吃饭,等所有人到齐开饭……

java.util.concurrent.CyclicBarrier

一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环的 barrier。

CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作很有用。

构造方法摘要

CyclicBarrier(int parties)           创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。

CyclicBarrier(int parties,Runnable barrierAction)           创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。

方法摘要

 int

await()     在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。

 int

await(long timeout,TimeUnit unit)           在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。

 int

getNumberWaiting()           返回当前在屏障处等待的参与者数目。

 int

getParties()           返回要求启动此 barrier 的参与者数目。

 boolean

isBroken()           查询此屏障是否处于损坏状态。

 void

reset()           将屏障重置为其初始状态。

例:

ExecutorService service =Executors.newCachedThreadPool();

final CyclicBarrier cb = newCyclicBarrier(3);  约定3个人

for (int i=0; i<3; i++)产生3个人

{     每个人的任务

       Runnablerunnable = newRunnable()

       {

              publicvoid run()

              {     开始出发到目的地

       Thread.sleep((long)Math.random()*1000);

       SOP(ThreadName即将到达集合点1,

当前已有cb.getNumberWaiting()+1个

+ (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"))

       cb.await();到了其他人没来就等

       人到齐了再继续进行

       Thread.sleep((long)Math.random()*1000);

       SOP(ThreadName即将到达集合点2)

       cb.await();到了其他人没来就等

 

}

}

service.execute(runnable);

}

 

 

 

 

public class CyclicBarrierTest {

 

       public static voidmain(String[] args) {

              ExecutorServiceservice = Executors.newCachedThreadPool();

              final  CyclicBarrier cb = new CyclicBarrier(3);

              for(inti=0;i<3;i++){

                     Runnablerunnable = new Runnable(){

                                   publicvoid run(){

                                   try{

                                          Thread.sleep((long)(Math.random()*10000));     

                                          System.out.println("线程" +Thread.currentThread().getName() +

                                                        "即将到达集合地点1,当前已有" +(cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));                                         

                                          cb.await();//三个线程都到这儿才走

                                         

                                          Thread.sleep((long)(Math.random()*10000));     

                                          System.out.println("线程" + Thread.currentThread().getName()+

                                                        "即将到达集合地点2,当前已有" +(cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));

                                          cb.await();      //三个线程都到这儿才走

                                          Thread.sleep((long)(Math.random()*10000));     

                                          System.out.println("线程" + Thread.currentThread().getName()+

                                                        "即将到达集合地点3,当前已有" + (cb.getNumberWaiting()+ 1) + "个已经到达," +(cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));                                      

                                          cb.await();      //三个线程都到这儿才走                                

                                   }catch (Exception e) {

                                          e.printStackTrace();

                                   }                         

                            }

                     };

                     service.execute(runnable);

              }

              service.shutdown();

       }

}

public class CyclicBarrierTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final  CyclicBarrier cb = new CyclicBarrier(3);
		for(int i=0;i<3;i++){
			Runnable runnable = new Runnable(){
					public void run(){
					try {
						Thread.sleep((long)(Math.random()*10000));	
						System.out.println("线程" + Thread.currentThread().getName() + 
								"即将到达集合地点1,当前已有" + (cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));						
						cb.await();
						
						Thread.sleep((long)(Math.random()*10000));	
						System.out.println("线程" + Thread.currentThread().getName() + 
								"即将到达集合地点2,当前已有" + (cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));
						cb.await();	
						Thread.sleep((long)(Math.random()*10000));	
						System.out.println("线程" + Thread.currentThread().getName() + 
								"即将到达集合地点3,当前已有" + (cb.getNumberWaiting() + 1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));						
						cb.await();						
					} catch (Exception e) {
						e.printStackTrace();
					}				
				}
			};
			service.execute(runnable);
		}
		service.shutdown();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值