CyclicBarrier适用于这样的情况:你希望创建一组任务,它们并行地执行工作,然后在下一个步骤之前等待,直到所有任务都完成。栅栏和闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行。

闭锁用于等待事件,而栅栏是线程之间彼此等待,等到都到的时候再决定做下一件事。可以参考Java并发工具类(闭锁CountDownLatch)

拿运动员的事情举例,运动员们跑到终点,互相等待所有人都到达终点后,再一起去做喝酒这件事。(运动员也许不能喝酒的,也许大家再跑一轮。)

下面用一个赛马程序来举例:

赛马

package concurrency;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import java.util.concurrent.*;

class Horse implements Runnable {

private static int counter = 0;

private final int id = counter++;

private int strides = 0;

private static Random rand = new Random(47);

private static CyclicBarrier barrier;

public Horse(CyclicBarrier b) {barrier = b;}

public synchronized int getStrides() {return strides;}

public void run() {

try {

while (!Thread.interrupted()) { //线程内不断循环

synchronized (this) {

strides += rand.nextInt(3); //每次马可以走0,1或者2步

}

barrier.await(); //走完后,就等所有其它马也走完,才能开始下一回合

}

} catch (InterruptedException e) {

} catch (BrokenBarrierException e) {

throw new RuntimeException(e);

}

}

@Override

public String toString() {

return "Horse " + id + " ";

}

public String tracks() {

StringBuilder s =new StringBuilder();

for(int i = 0; i < getStrides();i++)

s.append("*"); //这里打印每个马走的轨迹

s.append(id);

return s.toString();

}

}

public class HorseRace {

static final int FINISH_LINE = 75;

private List horses = new ArrayList();

private ExecutorService exec = Executors.newCachedThreadPool();

private CyclicBarrier barrier;

public HorseRace(int nHorses, final int pause) {

barrier = new CyclicBarrier(nHorses, new Runnable() {

@Override

public void run() {

StringBuilder s = new StringBuilder();

for (int i = 0; i < FINISH_LINE; i++) {

s.append("="); //打印赛道

}

System.out.println(s);

for (Horse horse : horses) {

System.out.println(horse.tracks()); //打印每匹马的轨迹

}

for (Horse horse : horses) {

if (horse.getStrides() >= FINISH_LINE) {

System.out.println(horse + "won!"); //每次检查,如果哪匹马到终点了,终止所有线程

exec.shutdownNow();

return;

}

}

try {

TimeUnit.MILLISECONDS.sleep(pause); //每走完一轮,暂停一小会输出

} catch (InterruptedException e) {

System.out.println("barrier-action sleep interrupted");

}

}

});

for (int i = 0; i < nHorses; i++) {

Horse horse = new Horse(barrier);

horses.add(horse);

exec.execute(horse); //所有马的线程开始执行

}

}

public static void main(String[] args) {

int nHorses = 7;

int pause = 200;

new HorseRace(nHorses, pause);

}

}

我们假设赛道长为75,马每次能走0,1或者2步,每次走完一轮后,互相等待。一旦所有马越过栅栏,它就会自动为下一回合的比赛做好准备。读者可以运行我的程序,在控制台上可以展示出一定的动画效果。

上面的例子中,我们向CyclicBarrier提供一个“栅栏动作”,它是一个Runnable,当计数值到达0时自动执行,这是CyclicBarrier和CountDownLatch之间的另一个区别。

public CyclicBarrier(int parties, Runnable barrierAction)

除此之外,CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。比如以下代码执行完之后会返回true。

java栅栏_Java并发工具类(栅栏CyclicBarrier)相关推荐

  1. java闭锁_Java并发工具类(闭锁CountDownLatch)

    闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态. CountDownLatch是一种灵活的闭锁实现,它可以使一个或者多个线程等待一组事件的发生. 闭锁状态包含一个计数器,该计数器被初始化为 ...

  2. java 栅栏_Java 并发工具类(栅栏 CyclicBarrier )

    CyclicBarrier适用于这样的情况:你希望创建一组任务,它们并行地执行工作,然后在下一个步骤之前等待,直到所有任务都完成.栅栏和闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行. ...

  3. 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)

    文章目录 八.Java中的并发工具类 8.1 等待多线程完成的CountDownLatch 8.2 同步屏障CyclicBarrier 8.2.1 CyclicBarrier简介 8.2.2 Cycl ...

  4. 《Java并发编程的艺术》读后笔记-Java中的并发工具类(第八章)

    文章目录 <Java并发编程的艺术>读后笔记-Java中的并发工具类(第八章) 1.等待多线程完成的CountDownLatch 2.同步屏障CyclicBarrier 2.1 Cycli ...

  5. 【搞定Java并发编程】第24篇:Java中的并发工具类之CountDownLatch

    上一篇:Java中的阻塞队列 BlockingQueue 详解 本文目录: 1.CountDownLatch的基本概述 2.CountDownLatch的使用案例 3.CountDownLatch的源 ...

  6. Java 中的并发工具类

    From: https://blog.wuwii.com/juc-utils.html java.util.concurrent 下提供了一些辅助类来帮助我们在并发编程的设计. 学习了 AQS 后再了 ...

  7. 《Java并发编程的艺术》读书笔记 - 第八章 - Java中的并发工具类

    目录 前言 等待多线程完成的 CountDownLatch 示例 同步屏障 CyclicBarrier 示例 CyclicBarrier 和 CountDownLatch 的区别 控制并发线程数量的 ...

  8. 死磕Java并发:J.U.C之并发工具类:CyclicBarrier

    作者:chenssy 来源:Java技术栈公众号 CyclicBarrier,一个同步辅助类,在API中是这么介绍的: 它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier ...

  9. JAVA线程并发数量控制_Java并发工具类(三):控制并发线程数的Semaphore

    作用 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 简介 Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数 ...

  10. 用java实现combin函数_Java并发工具类CompletableFuture教程与示例

    Java 8带来了大量的新功能和增强功能,例如Lambda表达式,Streams,CompletableFutures等.在本文中,我将通过简单的示例向您详细说明CompletableFuture及其 ...

最新文章

  1. MySQL数据库+命令大全+常用操作
  2. ubuntu和windows实现互相之间远程控制
  3. 批量域更改客户端本地administrator密码
  4. yum(Fedora和RedHat以及SUSE中的Shell前端软件包管理器)命令详解
  5. 原来数学才是世界上最浪漫的学科!
  6. email 添加附件 java_Java发送email 带附件 | 学步园
  7. 开源 = 打破商业垄断?
  8. easyui onclickrow 中获取列名_获取Chrome浏览器历史浏览记录实例
  9. c语言烟花表白程序代码,C语言实战之浪漫烟花表白程序代码
  10. 项目小记录—拼音码demo
  11. 荣耀MagicBook X桌面频繁蓝屏如何重装系统?
  12. 【USACO 2007 February Silver】农场派对
  13. 2022年种子行业分析
  14. python八进制表示_八进制python
  15. 网上免费平台学习美术
  16. 【北京迅为】i.MX6ULL终结者GPIO时钟
  17. Java中抽象类与方法的重写
  18. Python中的getattr()和__getattr__方法
  19. swift 2.0 ? ! 到底是什么意思
  20. 与OneNote 2007共享OneNote 2010笔记本

热门文章

  1. 使用富盛Sbo-Addon程序开发框架轻松开发模态单据选择查询功能实例
  2. 论数据库运维的全流程管控技术
  3. 技嘉显卡性能测试软件,显卡性能与超频:性能高于公版,超频潜力可圈可点
  4. 【PYTHON】利用Python爬取电影网站
  5. 程序员容易发福的原因及解决办法
  6. 小白网安学习日记(2) hacknet游戏(模拟黑客入侵的游戏)
  7. 链表(Linked List)的C语言实现
  8. 树和二叉树的应用 -- ---哈夫曼(Huffman)树和哈夫曼编码
  9. 深度学习(16) GAN(4)
  10. 什么叫组网_混合组网是什么意思