CyclicBarrier源码浅析

来源:互联网 发布:坐标数据库 编辑:程序博客网 时间:2024/06/05 21:11

CyclicBarrier内部实现很简单,利用ReentrantLock 和 Condition控制并发,

初始化的时候创建一个 计数器,每线程调用await方法的时候 计数器减1,再判断计数器是否等于0,

等于0的话,就唤醒所有 await的线程,不等于0的话,就调用condition的await方法等待 

public CyclicBarrier(int parties, Runnable barrierAction) {        if (parties <= 0) throw new IllegalArgumentException();        this.parties = parties;        this.count = parties;        this.barrierCommand = barrierAction;}


第一个参数parties就是计数器啦,第二个参数会 在唤醒所有等待线程之前 优先执行 barrierAction的run方法

为什么这里会区分parties 和count参数呢,因为CyclicBarrier支持重置,是一种可循环的,基本上parties变量初始化后

就不会变了, 每次调用await都是改变count的值

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; //每次调用await count都会减一            if (index == 0) {  //如果已经为0了,就会先调用构造函数中传入Runnable类执行(没传就不会调用)                boolean ranAction = false;                try {                    final Runnable command = barrierCommand;                    if (command != null)                        command.run();                    ranAction = true;                    nextGeneration();  //唤醒所有等待的线程,把count重置为parties,创建新的Generation类                    return 0;                } finally {                    if (!ranAction)                        breakBarrier();                }            }            //如果index不为0的话,就会在这里被阻塞            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 {                        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() {        // 唤醒所有trip.await()的线程        trip.signalAll();        // set up next generation        count = parties;        generation = new Generation();}

获取正在等待中的 线程数量

public int getNumberWaiting() {        final ReentrantLock lock = this.lock;        lock.lock();        try {            return parties - count;        } finally {            lock.unlock();        } }

重置CyclicBarrier类

public void reset() {        final ReentrantLock lock = this.lock;        lock.lock();        try {            breakBarrier();   // break the current generation            nextGeneration(); // start a new generation        } finally {            lock.unlock();        } }


原创粉丝点击