1. CyclicBarrier
CyclicBarrier:循環柵欄。循環柵欄允許一組線程互相等待,直到到達某個公共屏障點(common barrier point),然後所有的線程再同步向後執行。即N個線程相互等待(調用await()
方法),任何一個線程在完成之前,所有的線程必須等待。
2. CyclicBarrier簡單使用
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
new Thread(){
@Override
public void run(){
System.out.println("T1 start,,,,,,");
try {
TimeUnit.SECONDS.sleep(20);//阻塞20s
cyclicBarrier.await();//等待其他線程結束
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("T1 end。。。。。。");
}
}.start();
new Thread(){
@Override
public void run(){
System.out.println("T2 start,,,,,,");
try {
TimeUnit.SECONDS.sleep(10);//阻塞10s
cyclicBarrier.await();//等待其他線程結束
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("T2 end。。。。。。");
}
}.start();
}
}
運行結果:
T1 start,,,,,,
T2 start,,,,,,
T1 end。。。。。。
T2 end。。。。。。
解釋一下輸出結果的順序及時間:程序啓動後輸出T1 start,,,,,,
和T2 start,,,,,,
,但是在10秒之後並沒有輸出T2 end。。。。。。
,而是等到了20秒後(也就是T1阻塞結束之後)才一起輸出並結束。因此,CyclicBarrier是等待其他線程完成之後再一起往下執行。例子中是T2等待T1執行結束之後執行;
3. CyclicBarrier和CountDownLatch的區別
- CountDownLatch:一個線程或者多個線程等待另外N個線程完成某件事情之後(完成的標誌是調用countDown()方法)才能執行;
- CyclicBarrier:N個線程相互等待(調用await()方法),任何一個線程在完成之前,所有的線程必須等待。
- CountDownLatch的計數器只能使用一次,而CyclicBarrier的計數器可以使用reset()方法重置,可以使用多次,所以CyclicBarrier能夠處理更爲複雜的場景;