Java常见Lock(五): lock之CyclicBarrier
来源:互联网 发布:三维接线软件 编辑:程序博客网 时间:2024/05/22 01:31
CyclicBarrier
public class CyclicBarrier
- 又名回环栅栏或循环栅栏。
- 可重用。
成员变量
/** * 内部类 */ private static class Generation { boolean broken = false; } /** 可重复入锁 */ private final ReentrantLock lock = new ReentrantLock(); /** 利用Condition进行阻塞和唤醒 */ private final Condition trip = lock.newCondition(); /** 参与者数量 */ private final int parties; /* 参与者都执行完之后,从参与者中找一个线程执行该barrierCommand */ private final Runnable barrierCommand; /** The current generation */ private Generation generation = new Generation(); /** * 还在等待的参与者数量 */ private int count;
构造方法
/** * 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。 */ public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } /** * 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。 */ public CyclicBarrier(int parties) { this(parties, null); }
核心方法
boolean await(): 在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
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(); } }
int await(long timeout, TimeUnit unit):在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException { return dowait(true, unit.toNanos(timeout)); }
void reset(): 将屏障重置为其初始状态。
public void reset() { final ReentrantLock lock = this.lock; lock.lock(); try { breakBarrier(); // break the current generation nextGeneration(); // start a new generation } finally { lock.unlock(); } } /** * 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(); } /** * Updates state on barrier trip and wakes up everyone. * Called only while holding lock. */ private void nextGeneration() { // signal completion of last generation trip.signalAll(); // set up next generation count = parties; generation = new Generation(); }
从源码中看出,CyclicBarrier利用ReentrantLock保证线程安全,Condition保证等待和唤醒线程。
主要思想是初始化CyclicBarrier时,指定N个参与者,及一个栅栏动作barrierAction。
每个参与者完成一次任务,即执行await方法,还在等待参与者数量–count,当发现count !=0 时,说明还有参与者未参与,每个参与者自旋等待,等所有参与者都参与了,即count == 0时,所有参与者等待线程被唤醒,通俗的解释是每个参与者await方法后面代码可以继续执行,若设置了barrierAction,则第一个被唤醒的参与者等待线程执行该方法。
count可被重置,是与CountDownLatch的最大区别。
CyclicBarrier强调的是n个线程,参与者互相等待,只要有一个没完成count != 0,所有参与者都得等着。
CountDownLatch强调的是一个线程(或多个)需要等待另外的n个线程干完某件事情之后才能继续执行。
阅读全文
0 0
- Java常见Lock(五): lock之CyclicBarrier
- Java常见Lock(二): lock之ReentrantLock
- Java常见Lock(三): lock之ReadWriteLock、ReentrantReadWriteLock
- Java常见Lock(四): lock之Semaphore、CountDownLatch、StampedLock
- Java常见Lock(一): lock之Condition、ConditionObject、LockSupport
- (五)java多线程之Lock类
- java并发之Lock
- Java学习Lock.lock()
- JAVA之Lock简单认识
- java之Lock原理解析
- java并发锁之Lock
- Java 多线程之Lock接口
- Java并发编程之Lock
- Java并发编程之Lock
- java线程锁之lock
- Java并发编程之Lock
- java多线程之Lock介绍
- Java并发编程之Lock
- Hdu-6183 Color it(cdq分治)
- 关于C#中readonly的变量赋值问题。
- Java
- laravel 添加触发事件
- php curl请求https接口返回curl: (60) SSL certificate problem: unable to get local issuer certificate 错误
- Java常见Lock(五): lock之CyclicBarrier
- Python爬虫入门:爬虫基础了解
- 【2】coreML基于图像的处理(图像识别)
- js键盘键值
- [leetcode]第八周作业
- Newtonsoft.Json 转Json字符串为空不序列化
- Android Activity生命周期以及Fragment生命周期的区别与分析
- 分页查询时,把数据保存在session中,在点击下一页的时候取不到session中的值
- 上联网关中IP地址填写问题