Java并发包中CyclicBarrier的源码分析和使用
|
public CyclicBarrier(int parties) {
this(parties, null);
}
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
|
|
/** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
|
|
public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen
}
}
|
|
/**
* Main barrier code, covering the various policies.
*/
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
int index = --count;
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
// loop until tripped, broken, interrupted, or timed out
for (;;) {
try {
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
}
if (g.broken)
throw new BrokenBarrierException();
if (g != generation)
return index;
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}
|
|
private void nextGeneration() {
// signal completion of last generation
trip.signalAll();
// set up next generation
count = parties;
generation = new Generation();
}
/**
* Sets current barrier generation as broken and wakes up everyone.
* Called only while holding lock.
*/
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
nextGeneration和breakBarrier方法都可以停止阻塞。
|
|
public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
breakBarrier(); // break the current generation
nextGeneration(); // start a new generation
} finally {
lock.unlock();
}
}
|
|
package com.fpc.Test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Random;
public class CyclicBarrierTest {
private CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
private Random rnd = new Random();
class taskDemo implements Runnable{
private String taskId;
public taskDemo( String taskId ) {
this.taskId = taskId;
}
@Override
public void run() {
try {
int time = rnd.nextInt(1000);
Thread.sleep(time);
System.out.println(" Thread : " + taskId + " sleep : " + time + "ms");
try {
cyclicBarrier.await();
System.out.println(" Thread : " + taskId + " sleep is over");
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// CyclicBarrier cyclicBarrier = new CyclicBarrier();
public static void main( String[] args ) {
CyclicBarrierTest c = new CyclicBarrierTest();
ExecutorService pool = Executors.newCachedThreadPool();
pool.submit(c.new taskDemo("1"));
pool.submit(c.new taskDemo("2"));
pool.submit(c.new taskDemo("3"));
pool.submit(c.new taskDemo("4"));
}
}
|
|
Thread : 1 sleep : 102ms
Thread : 3 sleep : 254ms
Thread : 4 sleep : 394ms
Thread : 2 sleep : 943ms
Thread : 2 sleep is over
Thread : 1 sleep is over
Thread : 4 sleep is over
Thread : 3 sleep is over
|
|
Thread : 3 sleep : 166ms
Thread : 4 sleep : 281ms
Thread : 2 sleep : 444ms
Thread : 1 sleep : 776ms
|
|
Thread : 3 sleep : 500ms
Thread : 1 sleep : 567ms
Thread : 2 sleep : 912ms
Thread : 2 sleep is over
Thread : 3 sleep is over
Thread : 1 sleep is over
Thread : 4 sleep : 988ms
|
Java并发包中CyclicBarrier的源码分析和使用的更多相关文章
- Java并发编程中线程池源码分析及使用
当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...
- Spring中Bean命名源码分析
Spring中Bean命名源码分析 一.案例代码 首先是demo的整体结构 其次是各个部分的代码,代码本身比较简单,不是我们关注的重点 配置类 /** * @Author Helius * @Crea ...
- Java并发包中CyclicBarrier的工作原理、使用示例
1. CyclicBarrier的介绍与源码分析 CyclicBarrier 的字面意思是可循环(Cyclic)使用的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时 ...
- lesson2:java阻塞队列的demo及源码分析
本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...
- BIZ中model.getSql源码分析
功能:根据model.xml文件中配置的sql,获取对应的动态sql结果. 实例代码:String sql1 = model.getSql(dao.dbMeta());String sql2 = mo ...
- Java ThreadPoolExecutor线程池原理及源码分析
一.源码分析(基于JDK1.6) ThreadExecutorPool是使用最多的线程池组件,了解它的原始资料最好是从从设计者(Doug Lea)的口中知道它的来龙去脉.在Jdk1.6中,Thread ...
- 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...
- Java入门系列之集合HashMap源码分析(十四)
前言 我们知道在Java 8中对于HashMap引入了红黑树从而提高操作性能,由于在上一节我们已经通过图解方式分析了红黑树原理,所以在接下来我们将更多精力投入到解析原理而不是算法本身,HashMap在 ...
- Java入门系列之集合Hashtable源码分析(十一)
前言 上一节我们实现了散列算法并对冲突解决我们使用了开放地址法和链地址法两种方式,本节我们来详细分析源码,看看源码中对于冲突是使用的哪一种方式以及对比我们所实现的,有哪些可以进行改造的地方. Hash ...
随机推荐
- [SecureCRT] 解决 securecrt failed to open the host key database file 的问题
SecureCRT 在 Windows XP 和 Windows 7 中的个人应用数据路径是不同的,在 Windows 7 中,应用数据路径为:C:\Users\<username>\Ap ...
- C语言结构体和指针
指针也可以指向一个结构体,定义的形式一般为: struct 结构体名 *变量名; 下面是一个定义结构体指针的实例: struct stu{ char *name; //姓名 int num; //学号 ...
- DataSet转化为实体类【转】
分别转化单个类和集合两种方法. /// <summary> /// DataSet转换为实体类 /// </summary> /// <typeparam name=&q ...
- 剑指offer面试题6:重建二叉树
1.题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树. public class Solution { public TreeNode reConstructBinaryTree(int ...
- Ubuntu VMware出现提示No 3D support is available的解决方法
像我这样的Ubuntu脑残粉,电脑上只安装了Ubuntu,但是有时又必须得使用Windows,于是就装了一个Windows虚拟机,使用的是VMware,问题出在默认设置下启动虚拟机无法启动3D硬件加速 ...
- 【python】解决No module named _sqlite3的问题
环境版本说明: centos 7 python3.6.4 django 2.0 在创建django项目时候.报错以下信息 详细错误信息如下: 原因: 未安装sqlite 模块 解决: 1 安装 sql ...
- Android.mk (2) 函数进阶教程 - 分支、循环、子程序
https://www.jianshu.com/p/674dc7d7b4b0 函数进阶教程 - 分支.循环.子程序 按照面向过程程序设计的标准流程,我们讲完了顺序结构,就要讲分支.循环和子程序.下面我 ...
- 让人一看就懂的excel相对引用和绝对引用案例解析
http://www.ittribalwo.com/article/2831.html 内容提要:本文的excel相对引用和绝对引用.混合引用的使用方法案例截选自<Excel效率手册 早做完,不 ...
- vue之创建组建
vue的核心基础就是组件的使用,玩好了组件才能将前面学的基础更好的运用起来.组件的使用更使我们的项目解耦合.更加符合vue的设计思想MVVM. 那接下来就跟我看一下如何在一个Vue实例中使用组件吧! ...
- 7.22 python线程(3)
2018-7-22 10:28:29 回来啦! 6.条件 # !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/20 1 ...