您的位置:首页 > 编程语言 > Java开发

CyclicBarrier

2016-11-01 23:47 190 查看
The 
java.util.concurrent.CyclicBarrier
 class is a synchronization mechanism that can synchronize threads progressing through some algorithm. In other words, it is a barrier that all threads must wait at, until all threads
reach it, before any of the threads can continue. Here is a diagram illustrating that:

Two threads waiting for each other at CyclicBarriers.
The threads wait for each other by calling the 
await()
 method on the 
CyclicBarrier
. Once N threads are waiting at the 
CyclicBarrier
, all threads are
released and can continue running.


Creating a CyclicBarrier

When you create a 
CyclicBarrier
 you specify how many threads are to wait at it, before releasing them. Here is how you create a 
CyclicBarrier
:
CyclicBarrier barrier = new CyclicBarrier(2);



Waiting at a CyclicBarrier

Here is how a thread waits at a 
CyclicBarrier
:
barrier.await();


You can also specify a timeout for the waiting thread. When the timeout has passed the thread is also released, even if not all N threads are waiting at the 
CyclicBarrier
. Here is how you specify a timeout:
barrier.await(10, TimeUnit.SECONDS);


The waiting threads waits at the 
CyclicBarrier
 until either:
The last thread arrives (calls await() )
The thread is interrupted by another thread (another thread calls its interrupt() method)
Another waiting thread is interrupted
Another waiting thread times out while waiting at the 
CyclicBarrier

The 
CyclicBarrier.reset()
 method is called by some external thread.


CyclicBarrier Action

The 
CyclicBarrier
 supports a barrier action, which is a 
Runnable
 that is executed once the last thread arrives. You pass the 
Runnable
 barrier action
to the 
CyclicBarrier
 in its constructor, like this:
Runnable      barrierAction = ... ;
CyclicBarrier barrier       = new CyclicBarrier(2, barrierAction);



CyclicBarrier Example

Here is a code example that shows you how to use a 
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();


Here is the 
CyclicBarrierRunnable
 class:
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();
}
}
}


Here is the console output for an execution of the above code. Note that the sequence in which the threads gets to write to the console may vary from execution to execution. Sometimes 
Thread-0
 prints first, sometimes 
Thread-1
 prints
first etc.
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!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java concurrent