博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA并发,CyclicBarrier
阅读量:7082 次
发布时间:2019-06-28

本文共 9318 字,大约阅读时间需要 31 分钟。

CyclicBarrier 翻译过来叫循环栅栏、循环障碍什么的(还是有点别扭的。所以还是别翻译了,只可意会不可言传啊)。它主要的方法就是一个:await()。await() 方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。在这之后,如果再次调用 await() 方法,计数就又会变成 N-1,新一轮重新开始,这便是 Cyclic 的含义所在。

CyclicBarrier 的使用并不难,但需要主要它所相关的异常。除了常见的异常,CyclicBarrier.await() 方法会抛出一个独有的 BrokenBarrierException。这个异常发生在当某个线程在等待本 CyclicBarrier 时被中断或超时或被重置时,其它同样在这个 CyclicBarrier 上等待的线程便会受到 BrokenBarrierException。意思就是说,同志们,别等了,有个小伙伴已经挂了,咱们如果继续等有可能会一直等下去,所有各回各家吧。

CyclicBarrier.await() 方法带有返回值,用来表示当前线程是第几个到达这个 Barrier 的线程。

和 CountDownLatch 一样,CyclicBarrier 同样可以可以在构造函数中设定总计数值。与 CountDownLatch 不同的是,CyclicBarrier 的构造函数还可以接受一个 Runnable,会在 CyclicBarrier 被释放时执行。

NOTE: CyclicBarrier 的功能也可以由 CountDownLatch 来实现 

 

上面的内容参考自:

下面的例子引用thinking in java(网络上的简单例子体现不出CyclicBarrier存在的意义,和CountDownLatch的用处差不多)

 

1 package com.xt.thinks21_7;  2   3 //: concurrency/HorseRace.java  4 // Using CyclicBarriers.  5 import java.util.concurrent.*;  6 import java.util.*;  7   8 /**  9  * 马儿类 10  * @author Administrator 11  * 12  */ 13 class Horse implements Runnable { 14     private static int counter = 0; 15     private final int id = counter++; 16     private int strides = 0; 17     private static Random rand = new Random(47); 18     private static CyclicBarrier barrier; 19  20     public Horse(CyclicBarrier b) { 21         barrier = b; 22     } 23  24     public synchronized int getStrides() { 25         return strides; 26     } 27  28     public void run() { 29         try { 30             while (!Thread.interrupted()) { 31                 synchronized (this) { 32                     //马儿奔跑的不熟,可能是0步,1步,2步 33                     strides += rand.nextInt(3); // Produces 0, 1 or 2 34                 } 35                 //当前线程加入 36                 barrier.await(); 37                 /* 38                  * await的源码 39                  *  public int await() throws InterruptedException, BrokenBarrierException { 40                         try { 41                             return dowait(false, 0L); 42                         } catch (TimeoutException toe) { 43                             throw new Error(toe); // cannot happen 44                         } 45                     } 46                      47                     dowait的源码: 48                     private int dowait(boolean timed, long nanos) 49                         throws InterruptedException, BrokenBarrierException, 50                                TimeoutException { 51                         final ReentrantLock lock = this.lock; 52                         lock.lock(); 53                         try { 54                             final Generation g = generation; 55                  56                             if (g.broken) 57                                 throw new BrokenBarrierException(); 58                  59                             if (Thread.interrupted()) { 60                                 breakBarrier(); 61                                 throw new InterruptedException(); 62                             } 63                  64                             int index = --count; 65                             if (index == 0) {  // tripped 66                                 boolean ranAction = false; 67                                 try { 68                                     final Runnable command = barrierCommand; 69                                      */ 70                  71                 //这里需要注意,判断了CyclicBarrier构造器中的runnable接口是否为空,不为空回调run方法 72 //                                    if (command != null) 73 //                                        command.run(); 74                                      75                                     /* 76                                     ranAction = true; 77                                     nextGeneration(); 78                                     return 0; 79                                 } finally { 80                                     if (!ranAction) 81                                         breakBarrier(); 82                                 } 83                             } 84                  85                             // loop until tripped, broken, interrupted, or timed out 86                             for (;;) { 87                                 try { 88                                     if (!timed) 89                                         trip.await(); 90                                     else if (nanos > 0L) 91                                         nanos = trip.awaitNanos(nanos); 92                                 } catch (InterruptedException ie) { 93                                     if (g == generation && ! g.broken) { 94                                         breakBarrier(); 95                                         throw ie; 96                                     } else { 97                                         // We're about to finish waiting even if we had not 98                                         // been interrupted, so this interrupt is deemed to 99                                         // "belong" to subsequent execution.100                                         Thread.currentThread().interrupt();101                                     }102                                 }103                 104                                 if (g.broken)105                                     throw new BrokenBarrierException();106                 107                                 if (g != generation)108                                     return index;109                 110                                 if (timed && nanos <= 0L) {111                                     breakBarrier();112                                     throw new TimeoutException();113                                 }114                             }115                         } finally {116                             lock.unlock();117                         }118                  */119             }120         } catch (InterruptedException e) {121             // A legitimate way to exit122         } catch (BrokenBarrierException e) {123             // This one we want to know about124             throw new RuntimeException(e);125         }126     }127 128     /**129      * 打印马儿id130      */131     public String toString() {132         return "Horse " + id + " ";133     }134 135     /**136      * 打印马儿奔跑轨迹137      */138     public String tracks() {139         StringBuilder s = new StringBuilder();140         for (int i = 0; i < getStrides(); i++)141             s.append("*");142         s.append(id);143         return s.toString();144     }145 }146 147 /**148  * 马儿奔跑的类149  * @author Administrator150  *151  */152 public class HorseRace {153     static final int FINISH_LINE = 75;154     private List
horses = new ArrayList
();155 private ExecutorService exec = Executors.newCachedThreadPool();156 private CyclicBarrier barrier;157 158 public HorseRace(int nHorses, final int pause) {159 //CyclicBarrier构造器,第二个参数为回调接口,触发条件是await计数到0的时候,也就是所有线程已经加入CyclicBarrier160 barrier = new CyclicBarrier(nHorses, new Runnable() {161 public void run() {162 StringBuilder s = new StringBuilder();163 //打印栅栏164 for (int i = 0; i < FINISH_LINE; i++)165 s.append("="); // The fence on the racetrack166 System.out.println(s);167 //打印所有马儿的奔跑轨迹168 for (Horse horse : horses)169 System.out.println(horse.tracks());170 //如果有一个马儿奔跑到了终点,则取消执行器执行所有线程了171 for (Horse horse : horses)172 if (horse.getStrides() >= FINISH_LINE) {173 System.out.print(horse + "won!");174 exec.shutdownNow();175 return;176 }177 //每一次所有马儿奔跑一次之后休眠时间178 try {179 TimeUnit.MILLISECONDS.sleep(pause);180 } catch (InterruptedException e) {181 System.out.println("barrier-action sleep interrupted");182 }183 }184 });185 //加入所有马儿到线程列表,执行器执行线程列表(所有马儿奔跑)186 for (int i = 0; i < nHorses; i++) {187 Horse horse = new Horse(barrier);188 horses.add(horse);189 exec.execute(horse);190 }191 }192 193 public static void main(String[] args) {194 int nHorses = 7;195 int pause = 200;196 if (args.length > 0) { // Optional argument197 int n = new Integer(args[0]);198 nHorses = n > 0 ? n : nHorses;199 }200 if (args.length > 1) { // Optional argument201 int p = new Integer(args[1]);202 pause = p > -1 ? p : pause;203 }204 new HorseRace(nHorses, pause);205 206 }207 } /* (Execute to see output) */// :~

 

总结:

thinking in java上面的代码例子都是精华,不是网络上一般的博主能够写出来的,理解了对自己很有好处,及时一个知识点花上一个小时也可以。

但是美中不足的是:thinking in java中翻译过来有些地方阐述的不是很清楚(可能也是原著就没阐述清楚),例如。它主要的方法就是一个:await()。await() 方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。在这之后,如果再次调用 await() 方法,计数就又会变成 N-1,新一轮重新开始,这便是 Cyclic 的含义所在。这段话对CyclicBarrier的理解太重要了我认为。

转载于:https://www.cnblogs.com/wubingshenyin/p/4486582.html

你可能感兴趣的文章
57 Insert Interval
查看>>
[译] 2018 PHP 应用程序安全设计指北
查看>>
云计算基础之什么是云计算?
查看>>
10个实用的Django技巧和建议
查看>>
带你学C带你飞!
查看>>
html_03 | HTML——③ HTML 表单详解
查看>>
小猿圈解决vue权限问题的方案
查看>>
Express.js 解析 Post 数据类型的正确姿势
查看>>
关于UI设计行业的认识再到认识
查看>>
String类自带的字符串处理原生方法
查看>>
使用PHP+淘宝IP地址库接口获得IP所属地理位置
查看>>
我的友情链接
查看>>
Nginx白名单设置
查看>>
通过批处理文件使用7zip执行备份;将1日和15日的备份再另外备份;定时清理过期备份...
查看>>
安装 CentOS 时找不到硬盘的解决办法
查看>>
Java中的访问控制public,private,protected,package
查看>>
Foxmail 6.5在Windwos 7下无法编辑签名
查看>>
Putty 连接Centos服务器
查看>>
Active Diretory 目录服务相关命令
查看>>
建立属于自己的Cydia源,并获取cydia中的deb安装包,cyder不报错汉化版
查看>>