java.util.concurrent.CyclicBarrier
是一个具有通过一些算法让多个线程保持同步的同步机制的类。也就是,这个一个所有线程必须等待的栅栏,所有线程都不能继续直到所有线程到达栅栏,下图说明了这个:
|
在CyclicBarriers 中,两个线程互相等待 |
在CyclicBarrier
中,所有线程调用了await()
方法都会互相等待,直到N个线程都到达了CyclicBarrier
,那么所有线程就会得到释放并且继续往下运行。
创建CyclicBarrier
创建CyclicBarrier
可以指定当多少个线程等待到达时,可以释放。下面是创建CyclicBarrier的例子:
CyclicBarrier barrier = new CyclicBarrier(2);
在CyclicBarrier中等待:
这是个线程在CyclicBarrier 中等待:
barrier.await();
同样可以给等待的线程一个指定的超时时间,即使N个线程都没到达CyclicBarrier
,也可以被释放,下面是指定超时时间的例子:
barrier.await(10, TimeUnit.SECONDS);
等待线程在CyclicBarrier等待,直到:
- 最后一个线程到达 (调用了await() )
- 线程被其他线程打断(另外一个线程调用了它的interrupt() 方法)
- 其他等待的线程被打断
在CyclicBarrier等待的其他线程超时
- 某些额外的线程调用了
CyclicBarrier.reset()
方法
CyclicBarrier操作
CyclicBarrier支持barrier操作,这是一个Runnable,在最后一个线程到达时执行。将Runnable barrier操作传递给其构造函数中的CyclicBarrier,如下所示:
Runnable barrierAction = ... ;
CyclicBarrier barrier = new CyclicBarrier(2, barrierAction);
CyclicBarrier例子
下面是个 CyclicBarrier
例子
:
Runnable barrier1Action = new Runnable() {
public void run() {
System.out.println("BarrierAction 1 executed ");
}
};
Runnable barrier2Action = new Runnable() {
public void run() {
System.out.println("BarrierAction 2 executed ");
}
};
CyclicBarrier barrier1 = new CyclicBarrier(2, barrier1Action);
CyclicBarrier barrier2 = new CyclicBarrier(2, barrier2Action);
CyclicBarrierRunnable barrierRunnable1 =
new CyclicBarrierRunnable(barrier1, barrier2);
CyclicBarrierRunnable barrierRunnable2 =
new CyclicBarrierRunnable(barrier1, barrier2);
new Thread(barrierRunnable1).start();
new Thread(barrierRunnable2).start();
这是 CyclicBarrierRunnable类:
public class CyclicBarrierRunnable implements Runnable{
CyclicBarrier barrier1 = null;
CyclicBarrier barrier2 = null;
public CyclicBarrierRunnable(
CyclicBarrier barrier1,
CyclicBarrier barrier2) {
this.barrier1 = barrier1;
this.barrier2 = barrier2;
}
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +
" waiting at barrier 1");
this.barrier1.await();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +
" waiting at barrier 2");
this.barrier2.await();
System.out.println(Thread.currentThread().getName() +
" done!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
这是上面执行的结果,注意每次执行的结果可能不太一样,有时候先打印Thread-0
的第一个元素,有时候先打印Thread-1的第一个元素:
Thread-0 waiting at barrier 1
Thread-1 waiting at barrier 1
BarrierAction 1 executed
Thread-1 waiting at barrier 2
Thread-0 waiting at barrier 2
BarrierAction 2 executed
Thread-0 done!
Thread-1 done!
参考翻译:http://tutorials.jenkov.com/java-util-concurrent/cyclicbarrier.html