转 多线程 闭锁(Latch) 栅栏(CyclicBarrier)
.embody{
padding:10px 10px 10px;
margin:0 -20px;
border-bottom:solid 1px #ededed;
}
.embody_b{
margin:0 ;
padding:10px 0;
}
.embody .embody_t,.embody .embody_c{
display: inline-block;
margin-right:10px;
}
.embody_t{
font-size: 12px;
color:#999;
}
.embody_c{
font-size: 12px;
}
.embody_c img,.embody_c em{
display: inline-block;
vertical-align: middle;
}
.embody_c img{
width:30px;
height:30px;
}
.embody_c em{
margin: 0 20px 0 10px;
color:#333;
font-style: normal;
}

分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
-闭锁(Latch)
- 确保某个计算在其需要的所有资源都被初始化之后才继续执行。二元闭锁(包括两个状态)可以用来表示“资源R已经被初始化”,而所有需要R的操作都必须先在这个闭锁上等待。
- 确保某个服务在其依赖的所有其他服务都已经启动之后才启动。
- 等待直到某个操作的所有参与者都就绪在继续执行。(例如:多人游戏中需要所有玩家准备才能开始)
-栅栏(CyclicBarrier)
-例子:两个分别关于CountDownlatch和CyclicBarrier的例子
1、CountDownLatch
工人:
package LatchAndCyclicBarrier;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Work implements Runnable{
private CountDownLatch downLatch;
private String name;
public Work(CountDownLatch downLatch, String name){
this.downLatch = downLatch;
this.name = name;
}
public void run() {
this.doWork();
try{
TimeUnit.SECONDS.sleep(new Random().nextInt(10));
}catch(InterruptedException ie){
}
System.out.println(this.name + "活干完了!");
this.downLatch.countDown();
}
private void doWork(){
System.out.println(this.name + "正在干活!");
}
}
老板:
package LatchAndCyclicBarrier;
import java.util.concurrent.CountDownLatch;
public class Boss implements Runnable{
private CountDownLatch downLatch;
public Boss(CountDownLatch downLatch){
this.downLatch = downLatch;
}
public void run() {
System.out.println("老板正在等所有的工人干完活......");
try {
this.downLatch.await();
} catch (InterruptedException e) {
}
System.out.println("工人活都干完了,老板开始检查了!");
}
}
测试代码:
package LatchAndCyclicBarrier;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestLatch {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(3);
Work w1 = new Work(latch,"张三");
Work w2 = new Work(latch,"李四");
Work w3 = new Work(latch,"王二");
Boss boss = new Boss(latch);
executor.execute(w3);
executor.execute(w2);
executor.execute(w1);
executor.execute(boss);
executor.shutdown();
}
}
执行结果:
李四正在干活!
老板正在等所有的工人干完活......
王二正在干活!
张三正在干活!
李四活干完了!
王二活干完了!
张三活干完了!
工人活都干完了,老板开始检查了!
2、CyclicBarrier
package LatchAndCyclicBarrier;
import java.util.concurrent.CyclicBarrier;
public class CycWork implements Runnable {
private CyclicBarrier cyclicBarrier ;
private String name ;
public CycWork(CyclicBarrier cyclicBarrier,String name)
{
this .name =name;
this .cyclicBarrier =cyclicBarrier;
}
@Override
public void run() {
// TODO Auto-generated method stub
System. out .println(name +"正在打桩,毕竟不轻松。。。。。" );
try {
Thread. sleep(5000);
System. out .println(name +"不容易,终于把桩打完了。。。。" );
cyclicBarrier .await();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System. out .println(name +":其他逗b把桩都打完了,又得忙活了。。。" );
}
}
测试程序
package LatchAndCyclicBarrier;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CycTest {
public static void main(String[] args)
{
ExecutorService executorpool=Executors. newFixedThreadPool(3);
CyclicBarrier cyclicBarrier= new CyclicBarrier(3);
CycWork work1= new CycWork(cyclicBarrier, "张三" );
CycWork work2= new CycWork(cyclicBarrier, "李四" );
CycWork work3= new CycWork(cyclicBarrier, "王五" );
executorpool.execute(work1);
executorpool.execute(work2);
executorpool.execute(work3);
executorpool.shutdown();
}
}
运行结果:
李四正在打桩,毕竟不轻松。。。。。
张三正在打桩,毕竟不轻松。。。。。
王五正在打桩,毕竟不轻松。。。。。
李四不容易,终于把桩打完了。。。。
张三不容易,终于把桩打完了。。。。
王五不容易,终于把桩打完了。。。。
王五:其他逗b把桩都打完了,又得忙活了。。。
李四:其他逗b把桩都打完了,又得忙活了。。。
张三:其他逗b把桩都打完了,又得忙活了。。。
CountDownlatch和CyclicBarrierde 源码部分
1、CountDownLatch中的两个关键方法
public void countDown() { //对计数器减一 表示有一个事件已经发生了
sync.releaseShared(1);
}
public void await() throws InterruptedException { //等到计数器为0
sync.acquireSharedInterruptibly(1);
}
public final void acquireSharedInterruptibly (int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
public final boolean releaseShared (int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true ;
}
return false ;
}
protected boolean tryReleaseShared (int arg) {
throw new UnsupportedOperationException();
}
2、CyclicBarrier中的await()方法
public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen;
}
}
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();
}
}
count = parties;
提到 parties就不得不看看构造函数了
public CyclicBarrier(int parties) {
this(parties, null);
}
如上例子,我们构造了CyclicBarrier(3)那么此时的 count值为3,接着dowait源码,当index==0时,后面执行的
final Runnable command = barrierCommand;
其实是可以设置的,这个Runnable可以传进来,当我们希望所有线程都达到某一时刻之后,用什么线程执行接下来的工作,当没有传Runnable进来时,就继续执行(唤醒其他线程),否则就runnable.run()(唤醒其他线程之前执行)
- 顶
- 1
- 踩
- 0
转 多线程 闭锁(Latch) 栅栏(CyclicBarrier)的更多相关文章
- 并发编程 04——闭锁CountDownLatch 与 栅栏CyclicBarrier
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- 多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier
1.倒计时器CountDownLatch CountDownLatch是一个多线程控制工具类.通常用来控制线程等待,它可以让一个线程一直等待知道计时结束才开始执行 构造函数: public Count ...
- 多线程-栅栏CyclicBarrier
上一篇总结了闭锁CountDownLatch,这一篇总结一下栅栏CyclicBarrier.它们两者之间的区别主要是,闭锁是等待一个事件发生,比如上一篇的田径比赛,运动员等待裁判哨声一响就可以开始跑, ...
- 闭锁CountDownLatch与栅栏CyclicBarrier
https://blog.csdn.net/lmc_wy/article/details/7866863 闭锁CountDownLatch与栅栏CyclicBarrier 浅谈 java ...
- Java并发编程之闭锁与栅栏
一.前言 闭锁与栅栏是在多线程编程中的概念,因为在多线程中,我们不能控制线程的执行状态,所以给线程加锁,让其按照我们的想法有秩序的执行. 闭锁 CountDownLatch,实例化时需要传入一个int ...
- 栅栏——CyclicBarrier
栅栏CyclicBarrier和闭锁CountDownLatch类似,可以说它们都是用来计数,都能阻塞一组线程知道某个事件发生.不同的是闭锁用于等待事件,而栅栏用于等待其他线程. 在前一篇<Co ...
- Java多线程:CountDownLatch、CyclicBarrier 和 Semaphore
场景描述: 多线程设计过程中,经常会遇到需要等待其它线程结束以后再做其他事情的情况. 有几种方案: 1.在主线程中设置一自定义全局计数标志,在工作线程完成时,计数减1.主线程侦测该标志是否为0,一 ...
- Java并发编程原理与实战二十七:循环栅栏:CyclicBarrier
昨天我们学习了倒计数功能的等待,今天我们学习的是循环栅栏:CyclicBarrier.下面我们就开始吧: 1.CyclicBarrier简介CyclicBarrier,是JDK1.5的java.uti ...
- java高并发系列 - 第17天:JUC中的循环栅栏CyclicBarrier常见的6种使用场景及代码示例
这是java高并发系列第17篇. 本文主要内容: 介绍CyclicBarrier 6个示例介绍CyclicBarrier的使用 对比CyclicBarrier和CountDownLatch Cycli ...
随机推荐
- 使MySQL对表名不区分大小写
今天郁闷死了,在LINUX下调一个程序老说找不到表,但是我明明是建了表的,在MYSQL的命令行下也可以查到,为什么程序就找不到表呢? 后来请教了一个老师才搞定,原来是LINUX下的MYSQL默认是要区 ...
- 角摩网发布在线制作Epub、Mobi格式的电子书
原来cn的域名没有及时续约被人用了,现在用www.joymo.cc开始新的电子书制作之路. 目前支持Epub和Mobi格式,会陆续加入PDF和APK的电子书.
- Nuget server on IIS6 returns 404
Nuget server on IIS6 returns 404 when downloading package after upgrade 2011年9月2日 8:03:30 (GMT Dayli ...
- javascript实现浏览器窗口传递参数
a.html <html> <head> <title>主页面</title> <script language="javascript ...
- Node.js:Buffer(缓冲区)介绍及常用方法
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门 ...
- IIS6.0 开启Gzip与PHP Gzip
因为在做一个项目,项目里面服务器主要提供数据,但是数据多了文件就大了,比较浪费流量和时间,我们便用Gzip来处理.我在本机上是apache,服务器上是IIS6.0,用的是php,那么我就在这里分享一下 ...
- Android安装包相关知识汇总 (编译过程图给力)
转自: https://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=208008519&idx=1&sn=278b7793699 ...
- [Transducer] Make Transducer works for Iteratable collection and Object
We've seen how we can transduce from arrays or other iterables, but plain objects aren't iterable in ...
- 【pyhon】黑客用字典暴力破解Zip文件密码原理性展示
基本原理:用程序把字典文件里拟定好的密码一个个提取出来,去测试zip能否打开 字典文件pass.txt内容: 1224 2121 asdf abcd1234 dwsdsd dssds 程序代码: # ...
- div+css 和 xhtml+css是一回事么?
div+css 和 xhtml+css是一回事.只是说法不一样,表达得意思都是通过CSS定义DIV 布局. 那为什么地方要说成XHTML +css 呢? 以为我们做网站用CSS布局得时候不光是用了DI ...