java栅栏_Java并发工具类(栅栏CyclicBarrier)
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)相关推荐
- java闭锁_Java并发工具类(闭锁CountDownLatch)
闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态. CountDownLatch是一种灵活的闭锁实现,它可以使一个或者多个线程等待一组事件的发生. 闭锁状态包含一个计数器,该计数器被初始化为 ...
- java 栅栏_Java 并发工具类(栅栏 CyclicBarrier )
CyclicBarrier适用于这样的情况:你希望创建一组任务,它们并行地执行工作,然后在下一个步骤之前等待,直到所有任务都完成.栅栏和闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行. ...
- 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)
文章目录 八.Java中的并发工具类 8.1 等待多线程完成的CountDownLatch 8.2 同步屏障CyclicBarrier 8.2.1 CyclicBarrier简介 8.2.2 Cycl ...
- 《Java并发编程的艺术》读后笔记-Java中的并发工具类(第八章)
文章目录 <Java并发编程的艺术>读后笔记-Java中的并发工具类(第八章) 1.等待多线程完成的CountDownLatch 2.同步屏障CyclicBarrier 2.1 Cycli ...
- 【搞定Java并发编程】第24篇:Java中的并发工具类之CountDownLatch
上一篇:Java中的阻塞队列 BlockingQueue 详解 本文目录: 1.CountDownLatch的基本概述 2.CountDownLatch的使用案例 3.CountDownLatch的源 ...
- Java 中的并发工具类
From: https://blog.wuwii.com/juc-utils.html java.util.concurrent 下提供了一些辅助类来帮助我们在并发编程的设计. 学习了 AQS 后再了 ...
- 《Java并发编程的艺术》读书笔记 - 第八章 - Java中的并发工具类
目录 前言 等待多线程完成的 CountDownLatch 示例 同步屏障 CyclicBarrier 示例 CyclicBarrier 和 CountDownLatch 的区别 控制并发线程数量的 ...
- 死磕Java并发:J.U.C之并发工具类:CyclicBarrier
作者:chenssy 来源:Java技术栈公众号 CyclicBarrier,一个同步辅助类,在API中是这么介绍的: 它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier ...
- JAVA线程并发数量控制_Java并发工具类(三):控制并发线程数的Semaphore
作用 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 简介 Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数 ...
- 用java实现combin函数_Java并发工具类CompletableFuture教程与示例
Java 8带来了大量的新功能和增强功能,例如Lambda表达式,Streams,CompletableFutures等.在本文中,我将通过简单的示例向您详细说明CompletableFuture及其 ...
最新文章
- MySQL数据库+命令大全+常用操作
- ubuntu和windows实现互相之间远程控制
- 批量域更改客户端本地administrator密码
- yum(Fedora和RedHat以及SUSE中的Shell前端软件包管理器)命令详解
- 原来数学才是世界上最浪漫的学科!
- email 添加附件 java_Java发送email 带附件 | 学步园
- 开源 = 打破商业垄断?
- easyui onclickrow 中获取列名_获取Chrome浏览器历史浏览记录实例
- c语言烟花表白程序代码,C语言实战之浪漫烟花表白程序代码
- 项目小记录—拼音码demo
- 荣耀MagicBook X桌面频繁蓝屏如何重装系统?
- 【USACO 2007 February Silver】农场派对
- 2022年种子行业分析
- python八进制表示_八进制python
- 网上免费平台学习美术
- 【北京迅为】i.MX6ULL终结者GPIO时钟
- Java中抽象类与方法的重写
- Python中的getattr()和__getattr__方法
- swift 2.0 ? ! 到底是什么意思
- 与OneNote 2007共享OneNote 2010笔记本