Barrier是一个多线程编程中经常要用到的同步工具,尤其多用于大数据量的计算过程中的同步。本文以广为流程的Doug Lea的concurrent工具包的Barrier实现为例,进行一点探讨。在Doug Lea的concurrent工具包中,Barrier是一个接口,在concurrent包中提供了两个Barrier的实现:CyclicBarrier和Rendezvous。下面是Barrier接口的定义:
Barrier接口中的方法非常简单,parties()返回所有需要在屏障处同步的线程数;broken()返回一个标志,指示释放是否已被破坏。Barrier接口中并没有提供加入屏障的方法,而是在c和Rendezvous的Barrier实现中提供的。你可以会疑问,为什么不在Barrier接口中提供这些方法呢?因为这些实现的差异迥异,以至于很难在这些实现中提炼出一个共用的方法签名。比如,对于CyclicBarrier加入屏障的方法是:barrier(),
- public interface Barrier {
- /**
- * Return the number of parties that must meet per barrier
- * point. The number of parties is always at least 1.
- **/
- public int parties();
- /**
- * Returns true if the barrier has been compromised
- * by threads leaving the barrier before a synchronization
- * point (normally due to interruption or timeout).
- * Barrier methods in implementation classes throw
- * throw BrokenBarrierException upon detection of breakage.
- * Implementations may also support some means
- * to clear this status.
- **/
- public boolean broken();
- }
Barrier接口中的方法非常简单,parties()返回所有需要在屏障处同步的线程数;broken()返回一个标志,指示释放是否已被破坏。Barrier接口中并没有提供加入屏障的方法,而是在c和Rendezvous的Barrier实现中提供的。你可以会疑问,为什么不在Barrier接口中提供这些方法呢?因为这些实现的差异迥异,以至于很难在这些实现中提炼出一个共用的方法签名。比如,对于CyclicBarrier加入屏障的方法是:barrier(),
- // CyclicBarrier.java
- public int barrier() throws InterruptedException, BrokenBarrierException {
- return doBarrier(false, 0);
- }
- protected synchronized int doBarrier(boolean timed, long msecs)
- throws InterruptedException, TimeoutException, BrokenBarrierException {
- int index = --count_;
- if (broken_) {
- throw new BrokenBarrierException(index);
- }
- else if (Thread.interrupted()) {
- broken_ = true;
- notifyAll();