CyclicBarrier

来源:互联网 发布:nba步行者特纳体测数据 编辑:程序博客网 时间:2024/06/05 18:57

1.类声明:

//使一组线程互相等待,直到所有线程都到达了,才放行所有阻塞的线程。用了分代思想,只用初始化一次,parties会不变,count到达0时放行。public class CyclicBarrier{}

2.变量:

//所有的参与者,需要等待的线程数量 private final int parties; //还需要等待的线程数量   private int count;   //放行的同时,开启的新的线程       private final Runnable barrierCommand;

3.方法:

//放行所有    public CyclicBarrier(int parties, Runnable barrierAction) {        if (parties <= 0) throw new IllegalArgumentException();        this.parties = parties;        this.count = parties;        this.barrierCommand = barrierAction;    }    //进行计数器-1        public int await() throws InterruptedException, BrokenBarrierException {        try {            return dowait(false, 0L);        } catch (TimeoutException toe) {            throw new Error(toe); // cannot happen        }    }    //核心方法,计数器到到0时唤醒所有线程,否者一直被阻塞       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;            //如果计数器到达0            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();        }    }
原创粉丝点击