CyclicBarrier

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

  CyclicBarrier相似于CountDownLatch也是个计数器, 不一样的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规定的数目时,全部进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思同样,可当作是个障碍, 全部的线程必须到齐后才能一块儿经过这个障碍。 CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,全部其它线程被唤醒前被执行。java

构造方法摘要
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() 
          将屏障重置为其初始状态。

 

复制代码

1 package com.thread;
 2 import java.util.concurrent.CyclicBarrier;
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.Semaphore;
 6 
 7 public class CyclicBarrierTest {
 8 
 9     public static void main(String[] args) {
10         ExecutorService service = Executors.newCachedThreadPool();
11         final  CyclicBarrier cb = new CyclicBarrier(3);//建立CyclicBarrier对象并设置3个公共屏障点
12         for(int i=0;i<3;i++){
13             Runnable runnable = new Runnable(){
14                     public void run(){
15                     try {
16                         Thread.sleep((long)(Math.random()*10000));    
17                         System.out.println("线程" + Thread.currentThread().getName() + 
18                                 "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
19                         cb.await();//到此若是没有达到公共屏障点,则该线程处于等待状态,若是达到公共屏障点则全部处于等待的线程都继续往下运行
20                         
21                         Thread.sleep((long)(Math.random()*10000));    
22                         System.out.println("线程" + Thread.currentThread().getName() + 
23                                 "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
24                         cb.await();    
25                         Thread.sleep((long)(Math.random()*10000));    
26                         System.out.println("线程" + Thread.currentThread().getName() + 
27                                 "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
28                         cb.await();                        
29                     } catch (Exception e) {
30                         e.printStackTrace();
31                     }                
32                 }
33             };
34             service.execute(runnable);
35         }
36         service.shutdown();
37     }
38 }

复制代码

复制代码

线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点2,当前已有2个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候

复制代码

 

  若是在构造CyclicBarrier对象的时候传了一个Runnable对象进去,则每次到达公共屏障点的时候都最早执行这个传进去的Runnable,而后再执行处于等待的Runnable。若是把上面的例子改为下面这样:dom

复制代码

1 package com.thread;
 2 import java.util.concurrent.CyclicBarrier;
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.Semaphore;
 6 
 7 public class CyclicBarrierTest {
 8 
 9     public static void main(String[] args) {
10         ExecutorService service = Executors.newCachedThreadPool();
11         //final  CyclicBarrier cb = new CyclicBarrier(3);//建立CyclicBarrier对象并设置3个公共屏障点
12         final  CyclicBarrier cb = new CyclicBarrier(3,new Runnable(){
13             @Override
14             public void run() {
15                 System.out.println("********我最早执行***********");
16             }
17         });
18         for(int i=0;i<3;i++){
19             Runnable runnable = new Runnable(){
20                     public void run(){
21                     try {
22                         Thread.sleep((long)(Math.random()*10000));    
23                         System.out.println("线程" + Thread.currentThread().getName() + 
24                                 "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
25                         cb.await();//到此若是没有达到公共屏障点,则该线程处于等待状态,若是达到公共屏障点则全部处于等待的线程都继续往下运行
26                         
27                         Thread.sleep((long)(Math.random()*10000));    
28                         System.out.println("线程" + Thread.currentThread().getName() + 
29                                 "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
30                         cb.await();    //这里CyclicBarrier对象又能够重用
31                         Thread.sleep((long)(Math.random()*10000));    
32                         System.out.println("线程" + Thread.currentThread().getName() + 
33                                 "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
34                         cb.await();                        
35                     } catch (Exception e) {
36                         e.printStackTrace();
37                     }                
38                 }
39             };
40             service.execute(runnable);
41         }
42         service.shutdown();
43     }
44 }

复制代码

则结果以下:ide

复制代码

线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
********我最早执行***********
线程pool-1-thread-1即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已经到达,正在等候
********我最早执行***********
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
********我最早执行***********

复制代码

相关文章
相关标签/搜索