java barrier_Java - Latch和Barrier的区别

之所以把Latch与Barrier放在一起比较是因为他们给人一种相似的感觉。

他们都是阻塞一些行为直至某个事件发生,但Latch是等待某个事件发生,而Barrier是等待线程。

先比较一下JCIP中对二者的描述:

Latch

A latch is a synchronizer that can delay the progress of threads until it reaches its terminal state.

A latch acts as a gate: until the latch reaches the terminal state the gate is closed and no thread can pass, and in the terminal state the gate opens, allowing all threads to pass.

Once the latch reaches the terminal state, it cannot change state again, so it remains open forever.

Latches can be used to ensure that certain activities do not proceed until other one-time activities complete。

即,闭锁可以延迟线程执行直至达到相应的结束状态。闭锁就像一个大门,未到达结束状态相当于大门紧闭,不让任何线程通过。

而到达结束状态后,大门敞开,让所有的线程通过,但是一旦敞开后不会再关闭。

闭锁可以用来确保一些活动在某个事件发生后执行。

Barrier

CyclicBarrier allows a fixed number of parties to rendezvous repeatedly at a barrier point and is useful in parallel iterative algorithms that break down a problem into a fixed number of independent subproblems.

Threads call await when they reach the barrier point, and await blocks until all the threads have reached the barrier point.

If all threads meet at the barrier point, the barrier has been successfully passed, in which case all threads are released and the barrier is reset so it can be used again.

很多人都把Barrier直译为"栅栏",我也很喜欢这个叫法。

栅栏可以使一组执行在一处汇集,也就是说我们可以用栅栏将一个问题分解成多个独立的子问题,并在执行结束后在同一处进行汇集。

当线程到达汇集地后调用await,await方法会出现阻塞直至其他线程也到达汇集地。

如果所有的线程都到达就可以通过栅栏,也就是所有的线程得到释放,而且栅栏也可以被重新利用。

另外,下面javadoc中对二者之间区别的说明:

A CountDownLatch is initialized with a given count.

The await methods block until the current count reaches zero due to invocations of the countDown method, after which all waiting threads are released and any subsequent invocations of await return immediately.

This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

闭锁从来都是带着事件的触发次数。

await方法会一直阻塞至countDown方法将次数变成0为止,所有的线程被释放才能进行后续的工作。

但这种现象只能出现一次,也就是说触发次数不会被重置。

如果你想要一个可重置次数的闭锁,那就用栅栏。

Another typical usage would be to divide a problem into N parts, describe each part with a Runnable that executes that portion and counts down on the latch, and queue all the Runnables to an Executor.

When all sub-parts are complete, the coordinating thread will be able to pass through await.

(When threads must repeatedly count down in this way, instead use a CyclicBarrier.)

这种行为阻塞的典型用法之一就是将某个问题分成多个部分,每个部分用不同的线程负责,并记得减少闭锁设置的次数。

当所有线程的工作结束后将通过await方法造成的阻塞,如果我们需要反复进行这样的工作就需要使用栅栏。

好了,既然Doug Lea老师将同一个观点阐述了这么多遍,剩下就是放心大胆地使用了,也许我们将问题想得太复杂了。

下面贴出栗子,由一个startGate拦住所有线程的执行,当所有线程就绪完成后调用countDown将它们释放,而另一扇大门——endGate后面正等着计算执行时间,而endGate等待的事件由这些线程触发:

public class TestHarness {

public static long timeTasks(int nThreads, final Runnable task)

throws InterruptedException {

final CountDownLatch startGate = new CountDownLatch(1);

final CountDownLatch endGate = new CountDownLatch(nThreads);

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

Thread t = new Thread() {

public void run() {

try {

startGate.await();

try {

task.run();

} finally {

endGate.countDown();

}

} catch (InterruptedException ignored) {

}

}

};

t.start();

}

long start = System.nanoTime();

startGate.countDown();

endGate.await();

long end = System.nanoTime();

return end - start;

}

}

执行看看:

public static void main(String[] args) throws ExecutionException, InterruptedException {

System.out.println("cost :::"+TestHarness.timeTasks(10,new Runnable() {

@Override

public void run() {

int num = RandomUtils.nextInt(0,100);

if(num>50) try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Alvez ::"+ num);

}

}));

}

接着试试栅栏,没有搞任何复杂的东西,注意countSupposed%partyCount,主要是想用这个体现一下栅栏是否可以反复使用多次。

如果countSupposed%partyCount的结果恰好为0,所有线程执行结束后,主线程也会正常结束。

反之则会一直阻塞下去,如果countSupposed%partyCount结果大于1且不为0,其结果就是我们看到"let's go to the barrier !!"出现的次数:

public static void barrierTest(int partyCount, int countSupposed) {

if(partyCount<1 || countSupposed < 1) throw new IllegalArgumentException();

final CyclicBarrier barrier = new CyclicBarrier(partyCount,new Runnable() {

@Override

public void run() {

System.out.println("let's go barrier !!");

}

});

System.out.println(countSupposed%partyCount==0?"let's show the smooth!!":"....but blocked");

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

Runnable runnable = new Runnable() {

@Override

public void run() {

try {

barrier.await();

System.out.println(Thread.currentThread().getName() + " show!!");

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

}

};

new Thread(runnable).start();

}

}

执行:

public static void main(String[] args) {

barrierTest(11, 20);

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/538468.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kingback小组冲刺博客

一、6月13日 1、今日完成的任务 李可欣 项目首页的框架设计 项目首页的导航栏部分 对于项目的配色进行了改进&#xff0c;并且设计了logo 杨帆 今天进行了数据库的设计&#xff0c;完成了数据库的增删改查&#xff0c;并建立了两个jsp页面&#xff0c;还学习了一些数据库设计的…

用python前端html后端django_浅谈Django前端后端值传递问题

前端后端传值问题总结前端传给后端通过表单传值1、通过表单get请求传值在前端当通过get的方式传值时&#xff0c;表单中的标签的name值将会被当做action的地址的参数此时&#xff0c;在后端可以通过get请求相应的name值拿到对应的value值例子:html中:{% csrf_token %}类别{% fo…

使用Git上传本地项目到oschina

原文地址&#xff1a;https://my.oschina.net/158/blog/530112 --------------------------------------------- 1.首先看一下自己是否有公钥&#xff0c; 在 我的资料-->SSH公钥 查看&#xff0c;如果没有&#xff0c;添加自己的SSH 公钥&#xff1a; SSH key 可以让你在…

手动创建git忽略push清单,node_module以及自身

1.文件夹内右键git bash&#xff0c;输 touch .gitignore&#xff0c;注意中间有空格 2.编辑器打开生成的 .gitignore 文件&#xff0c;加入 .gitignore node_modules12 3.保存 4.以后再push到仓库的就会过滤这俩了&#xff0c;想加啥自己加

整数数组按绝对值排序

2019独角兽企业重金招聘Python工程师标准>>> 题目&#xff1a; 给出一组整数数组&#xff0c;要求按照绝对值从小到大进行排序后输出。 可以用经典的冒泡排序法来计算此问题&#xff0c;计算过程&#xff1a; 1、比较相邻两个元素绝对值&#xff0c;如果第一个比第二…

python定时任务是异步的吗_定时任务、异步任务

------------定时任务、异步任务--------pip install celery --targetD:\Users\ex-ouyangl003\PycharmProjects\data_new\dg_meta_system\metadata_system\venv\Lib\site-packages# coding:utf-8from apscheduler.schedulers.blocking import BlockingSchedulerimport datetime…

java excel自动保存_java读取excel的内容(可保存到数据库中)

//**poi jar包//public classReadExcel {SuppressWarnings("static-access")private staticString getValue(HSSFCell hssfCell) {if (hssfCell.getCellType() hssfCell.CELL_TYPE_BOOLEAN) {//返回布尔类型的值returnString.valueOf(hssfCell.getBooleanCellValue()…

《快学Scala》勘误

原文链接&#xff1a;http://www.blogjava.net/sean/archive/2012/11/15/391386.html ---------------- 第11页&#xff08;练习&#xff09;&#xff1a; 在Scala REPL中键入3&#xff0c;然后按Tab键 应为 在Scala REPL中键入3.&#xff0c;然后按Tab键 第19页&#xff0…

二分排序java实现

1.什么是二分排序&#xff1a; 二分排序是指利用二分法的思想对插入排序进行改进的一种插入排序算法&#xff0c;不同于二叉排序&#xff0c;可以利用数组的特点快速定位指定索引的元素&#xff1b; 算法思想&#xff1a;二分法插入排序是在插入第i个元素时&#xff0c;对前面的…

pearson相关系数_pearson相关系数与典型相关性分析(CCA)

本文主要介绍相关系数的概念&#xff0c;以及简单相关系数中的pearson相关系数及其局限性。随后介绍pearson相关系数无法解决的问题(两个变量组之间的相关性问题)的解决方案。1、pearson相关系数在日常中&#xff0c;我们经常会遇到一些关于相关性的分析&#xff0c;例如&#…

快学Scala习题解答—第三章 数组相关操作

原文链接&#xff1a;http://blog.csdn.net/ivan_pig/article/details/8257365 -------------------------------------------------- 4 数组相关操作 4.1 编写一段代码&#xff0c;将a设置为一个n个随机整数的数组&#xff0c;要求随机数介于0(包含)和n(不包含)之间 random和…

seo自动工具_爱站SEO工具包详细介绍

爱站SEO工具-seoer的瑞士军刀&#xff01;这个工具主要是为了方便SEOer查询一些网站的问题&#xff0c;监控关键词排名收录等等&#xff0c;新手老手都可以用的工具&#xff0c;更快的让SEOer上手。相信有很多SEOer都使用过爱站SEO工具包&#xff0c;也有很多新入行的小伙伴可能…

人物三(依芙蒂法)

转载于:https://www.cnblogs.com/song1900/p/9189921.html

常用Oracle分析函数详解

原文链接&#xff1a;http://www.cnblogs.com/benio/archive/2011/06/01/2066106.html --------------------------------------------------------------------------- 学习步骤&#xff1a; 1. 拥有Oracle EBS demo 环境 或者 PROD 环境 2. copy以下代码进 PL/SQL 3. 配合解…

XML文件结构和基本语法

XML文件的结构性内容&#xff0c;包括节点关系以及属性内容等等。元素是组成XML的最基本的单位&#xff0c;它由开始标记&#xff0c;属性和结束标记组成。就是一个元素的例子&#xff0c;每个元素必须有一个元素名&#xff0c;元素可以若干个属性以及属性值。 xml文件和html文…

python表格数据分类聚合_3-python数据分析-pandas高级操作之替换、映射、随机抽样、分组、高级数据聚合、数据加载、透视表、交叉表...

3-python数据分析-pandas高级操作之替换、映射、随机抽样、分组、高级数据聚合、数据加载、透视表、交叉表替换操作 replace替换操作可以同步作用于Series和DataFrame中单值替换普通替换&#xff1a; 替换所有符合要求的元素:to_replace15,value’e’按列指定单值替换&#xff…

oracle-SQL-case when 改用 DECODE

SELECT CASE FLOOR_LINE_ID WHEN 1 THEN 高铁 WHEN 2 THEN 高速 WHEN 3 THEN 公路 WHEN 5 THEN 地铁 ELSE 其他 END AS LINE_NAME, FLOOR_LINE_ID FROM ( SELECT FLOOR(LINE_ID/100) AS FLOOR_LINE_ID FROM DT4_LINE_NAME ) 改…

lcp mysql cluster_Mysql Cluster 非root用户启动ndbd节点报错

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼1.配置文件&#xff0c;如下&#xff1a;[rootcent178 ~]# ls -lart /etc/my.cnf-rw-rw-r-- 1 mysql mysql 3055 Oct 31 17:29 /etc/my.cnf2.集群数据存储文件夹&#xff0c;如下&#xff1a;[rootcent178 ~]# ls -lart /var/lib/m…

fatal: Could not read from remote repository.的解决办法

原文地址&#xff1a;http://blog.csdn.net/huahua78/article/details/52330792 --------------------------------------------------------------------------------- 查看远端地址 git remote –v 查看配置 git config --list git status git add . // 暂存所有的更改git…

python中mako中loop_python中Mako库实例用法

Mako是一个模板库。一种嵌入式的语言&#xff0c;能够实现简化组件布局以及继承&#xff0c;主要的用途也是和作用域有关&#xff0c;但是效果是最直接切灵活的&#xff0c;这些都是mako的基本功能&#xff0c;掌握了基础内容&#xff0c;接下来就是详细的了解讲述&#xff0c;…