一个cyclicbarrier让一堆的线程处于等待状态,它们彼此之间会有相同的阻碍点。这个阻碍是循环的,因为当等待的线程等到释放且,它可能会被重复利用。这个同步器在应用的程序中是非常有用的,它会执行一个固定大小的线程,偶尔必须等待每一个线程。

java.util.concurrent.CyclicBarrier类继续一个循环的阻碍同步器。你可以通过执行这个类的CyclicBarrier(int parties)的构造器去明确实例化一个CyclicBarrier的实例。当parties的值小于1时,这个构造器将会抛出IllegalArgumentException。

实际上你也执行CyclicBarrier(int parties, Runnabl barrierAction)的构造器去初始化一个循环的阻碍部分;其中的当阻碍被执行时,barrierAction将会执行。换句话说,parties -1个线程在等待,当多个线程到达时,到达的线程将会执行barrierAction和所有线程都会向前执行。这个runnable在所有线程都在执行时,而去更新分享的状态是非常的用的。当parties的值小于1时,就会抛出IllegalArgument的错误。(在前面的构造器执行这个构造器时,如果放入的barrierAction为null,那么当阻碍释放后,将没的线程会被执行。)

CyclicBarrier也提供了如下的方法:

1)        int await():强迫正在请求的线程处于等待状态,直到所有部分在cyclic barrier中都执行await()的方法。当它或其它等待线程被打断,或其它线程在等待时超时,或在这个cyclic barrier中执行reset()的方法,那么在请求的线程会停止等待。如果正在请求的线程自己在进行执行时被打断,或在等待中被打断,这个方法将会抛出InterruptedException,并且请求的线程打断状态会被清空。任何线程在等待时被执行reset()的方法,或执行await()时被打断,或任何等待线程被打断,那么将会抛出BrokenBarrierException.当在等待时被打断,或者等待的线程抛出BrokenBarrierException,那么障碍(barrier)都会处于打断状态。如果请求的线程是最后一个到达,和构造器的barrierAction不为null,在允许其它线程继续执行前,将会让请求的线程去执行。这个方法将会返回请求线程的索引值,这里的索引getParties()-1说明从第一个线程到达到最后一个线程的达到。

2)        int await(long timeout,TimeUnit unit):这个方法与前面的方法是相似的,唯一不一样的是,它让你明确要多长时间让请求的线程进入到等待状态。在线程等待期间而超时了,那么将会抛出java.util.concurrent.TimeoutException.

3)        int getNumberWaiting():返回当前阻碍下等待的线程数量。这个方法对于打debug和输出信息很有用。

4)        int getParties():返回需要调用障碍(barrier)的数量。

5)        boolean isBroken():当一个或更多个部分被这个barrier打断,因为打断、超时、重置,或因为异常的抛出错误,这个方法将会返回true,其它情况返回false.

6)        void reset():重置这个障碍(barrier)去初始化它的状态。如果任何在障碍(barrier)中等待,那么将会抛出BrokenBarrierException.

Cyclicbarriers在平形分隔的情况是很有用的。当一个长任务被分解为多个子任务,然后将子任务执行的结果再合并成一个结果返回。如下的Listing6-2的例子。

Listing6-2

package com.owen.thread.chapter6;import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierDemo
{public static void main(String[] args){float[][] matrix = new float[3][3];int counter = 0;for (int row = 0; row < matrix.length; row++)for (int col = 0; col < matrix[0].length; col++)matrix[row][col] = counter++;dump(matrix);System.out.println();Solver solver = new Solver(matrix);System.out.println();dump(matrix);}static void dump(float[][] matrix){for (int row = 0; row < matrix.length; row++){for (int col = 0; col < matrix[0].length; col++)System.out.print(matrix[row][col] + " ");System.out.println();}}
}class Solver
{final int N;final float[][] data;final CyclicBarrier barrier;class Worker implements Runnable{int myRow;boolean done = false;Worker(int row){myRow = row;}boolean done(){return done;}void processRow(int myRow){System.out.println("Processing row: " + myRow);for (int i = 0; i < N; i++)data[myRow][i] *= 10;done = true;}@Overridepublic void run(){while (!done()){processRow(myRow);try{barrier.await();} catch (InterruptedException ie){return;} catch (BrokenBarrierException bbe){return;}}}}public Solver(float[][] matrix){data = matrix;N = matrix.length;barrier = new CyclicBarrier(N, new Runnable(){@Overridepublic void run(){mergeRows();}});for (int i = 0; i < N; ++i)new Thread(new Worker(i)).start();waitUntilDone();}void mergeRows(){System.out.println("merging");synchronized ("abc"){"abc".notify();}}void waitUntilDone(){synchronized ("abc"){try{System.out.println("main thread waiting");"abc".wait();System.out.println("main thread notified");} catch (InterruptedException ie){System.out.println("main thread interrupted");}}}
}

首先主线程创建一个浮点型的数组,然后通过dump的方法,将创建的数组值输出。然后线程会去实例化Solver的对象,这里会分隔线程去计算每一行的值。也就是说修改原告数组内的值,只是按行分隔修改。

Solver出现一个构造器,这个构造器中会去接收数组的值的,并且保存它的引用,当然还就是定义一个参数N去保存数组的大小。构造器创建一个有N部分和一个障碍(barrier)的执行动作的cyclic barrier。在障碍(barrier)的执行中,是将数组计算的所有行的结果合并放入到数组中的。最后,构造器创建一个工作的线程,这个工作线程会被切分多个工作执行,就是去修改每一行的矩阵值。构造器会处于等待状,直到所有的工作都完成。

Worker会重复地去执行run()方法,执行run()方法会去执行processRow()的方法,这个方法会明确去修改矩阵行的值,直到done()返回true的值,方法才会停止执行。当明确processRow()的方法执行完了,那么就会执行await()的方法,线程就不能继续前进。

最为关键的是,所有工作线程都会执行await()的方法。当最后一个工作线程执行好了矩阵的修改后,就会执行await()的方法,然后触发障碍(barrier)的动作,使用刚刚执行的所有工作线程合并成一个矩阵的结果。在这个例子是,合并不是必须的,但是在更为复杂的例子中,合并是必须的。

最后任务执行mergeRows()的方法,去唤醒主线程执行Solver的构造器。这个线程连接着一个字符串“abc”对象,使线程处于等待状态。调用notify()的方法,仅仅是唤醒在这个监听器中的等待线程。

执行上面的代码,你可能会得到相似的结果:

0.0 1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0 Processing row: 0
main thread waiting
Processing row: 1
Processing row: 2
merging
main thread notified0.0 10.0 20.0
30.0 40.0 50.0
60.0 70.0 80.0

6.2阻碍循环(Cyclic Barriers)相关推荐

  1. JAVA核心知识总结

    本文来说下常见的JAVA基础面试题,部分资源来自于网络,看下你是不是都已经掌握了.后面会持续更新 文章目录 说说进程和线程的区别 Object 的 wait()和notify() 方法 并发特性 - ...

  2. 数据结构与算法 学习笔记(中)

    油管上的CS61B的视频 学习代码 随看随记 Dijkstra's algorithm再理解 Asymptotics 本意是渐近的意思:这里代指当参数为无穷大时,所需要进行运算的次数,和我们常说的复杂 ...

  3. 《Android Studio 实战》总结一

    Android Studio 实战 Adam Gerber.Clifton Craig著 靳晓辉.张文书 译,清华大学出版社 目录 Android Studio 实战 1 第一章 Android St ...

  4. AutoML-第七章-AutoNet

    第七章:自动调整的深度神经网络 摘要 AutoML 的最新进展产生了可以与机器学习专家在监督学习任务上竞争的自动化工具.在这项工作中,我们介绍了两个版本的 Auto-Net ,它们提供了自动调整的深度 ...

  5. 嵌入式开发板硬件操作入门学习9——集成电路芯片手册术语词汇表(中英文对照)

    原创链接:集成电路芯片半导体中英文对照术语词汇表 英语 中文 1-9 10 gigabit 10 Gb 1st Nyquist zone 第一奈奎斯特区域 3D full‑wave electroma ...

  6. java基础综合练习(嗖嗖移动)

    功能列表: 服务器端代码: 1 package cn.luoxue.server; 2 3 import java.io.IOException; 4 import java.net.Datagram ...

  7. DeviceNet技术及其产品开发

    DeviceNet技术及其产品开发 2008-2-28 10:53:00 来源:作者: 网友评论 0条 点击查看 <script src="http://www.ca800.com/a ...

  8. 无需外源库Python小游戏

    本来想写个解密dll异或加密的脚本,但是发现没什么dll游戏了找dll异或加密更是难上加难 于是打开CSDN寻找好玩的 找到了一个大佬的小游戏教程,做出了一些更改 改后设置一键关闭和跳出分循环不会导致 ...

  9. 集成电路芯片半导体中英文对照术语词汇表(转)

    转载自:集成电路芯片半导体中英文对照术语词汇表 英语 中文 1-9 10 gigabit 10 Gb 1st Nyquist zone 第一奈奎斯特区域 3D full‑wave electromag ...

  10. [抽象代数]英语词汇

    Additive group 加法群 Algebra 代数 Algebraic element 代数元素 algebraic integer 代数整数 Algebraically independen ...

最新文章

  1. Kaggle入门,看这一篇就够了
  2. ramdisk plus v11.5安装内存虚拟硬盘
  3. 自学python要看哪些书籍-Python入门自学到精通需要看哪些书籍?
  4. 数据产品必备技术知识:机器学习及常见算法,看这一篇就够了
  5. 一直都很喜欢的软件--基于平台
  6. Android语音录入与邮件发送
  7. 需求分析——使用类图建模
  8. [python][os]分离文件目录,文件名以及文件后缀
  9. CF16E Fish(状压+期望dp)
  10. BMCBIOS全擦升级
  11. 你画我猜游戏html源代码,微信小程序你画我猜demo完整源码
  12. PR(Premiere) 鼓点节拍插件Beat Edit,打不开的原因
  13. 怎么在计算机里找到CF里保存的视频,cf录像保存在哪?cf怎么样录像保存方法
  14. 【CRH】列车通过曲线时,曲线半径、超高值与车速的关系
  15. Web自动化测试教程
  16. 博客阅读:图解Transformer(The Illustrated Transformer)
  17. yii2实战之初见端倪
  18. Windows操作系统常见故障
  19. 借名买房规避限购政策的,合同应认定为无效
  20. php许愿墙模板,PHP+jQuery+Ajax漂亮的许愿墙效果

热门文章

  1. js限制文本框只能输入数字方法小结(转)
  2. Servlet详细介绍
  3. SharePoint 2013创建WCF REST Service
  4. Python Project Euler 013:100个50位数和
  5. hdu 1698 Just a Hook
  6. 游戏筑基开发之字符串的注意点(C语言)
  7. Linux iptables防火墙详解(四)——配置实战
  8. VGMP报文封装格式简介
  9. urllib.error.URLError: <urlopen error [SSL: WRONG_VERSION_NUMBER] wrong version number 成功解决
  10. 使用linux服务器实现路由器的功能(实验)