天天看點

java線程栅欄_java多線程應用_并發工具類之循環屏障(CyclicBarrier)

java多線程應用_并發工具類之循環屏障(CyclicBarrier)

CyclicBarrier這個類的字面意思是循環屏障,跟CountDownLatch有些像,但不一樣。關于CountDownLatch我在該爬蟲項目中使用過,沒有單獨的文章進行講解。

CyclicBarrier跟CountDownLatch的差別是:

CountDownLatch隻計數1次

CyclicBarrier可以通過reset()重置計數,實作更複雜的業務,也會在其等待完畢釋放鎖後重置計數。

說明:

CyclicBarrier有2個構造

CyclicBarrier(int parties) 設定一個任務的參與數

CyclicBarrier(int parties,Runnable barrierAction) 設定一個任務的參與數和優先執行的barrierAction

步驟:

1、設定任務參與數,每個參與數達到相應階段後,執行await方法。

2、當最後一個參與者進入await的階段後,則停止阻塞

注意: barrierAcction屏障動作是由最後一個達到的子線程執行的

可以看我下面的代碼,以學生去郊遊為例,展示了其線程阻塞和可循環使用的功能:

package top.yibobo.test;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {

public static void main(String[] args) {

test();

}

private static void test() {

CyclicBarrier cb = new CyclicBarrier(5, () ->

System.out.println(Thread.currentThread().getId() + "~~大家都到齊了,出發幹下件事咯"));

for (int i = 0; i < 5; i++) {

new Thread(() -> {

System.out.println(Thread.currentThread().getId() + " 學生 已達到學校門口");

await(cb);

System.out.println(Thread.currentThread().getId() + " 學生 已經坐上 旅遊大巴");

await(cb);

System.out.println(Thread.currentThread().getId() + " 學生到達景點");

await(cb);

}).start();

}

}

private static void await(CyclicBarrier cb){

try {

cb.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

}

}

輸出語句為:

12 學生 已達到學校門口

13 學生 已達到學校門口

11 學生 已達到學校門口

14 學生 已達到學校門口

15 學生 已達到學校門口

15~~大家都到齊了,出發幹下件事咯

15 學生 已經坐上 旅遊大巴

13 學生 已經坐上 旅遊大巴

14 學生 已經坐上 旅遊大巴

11 學生 已經坐上 旅遊大巴

12 學生 已經坐上 旅遊大巴

12~~大家都到齊了,出發幹下件事咯

12 學生到達景點

13 學生到達景點

15 學生到達景點

11 學生到達景點

14 學生到達景點

14~~大家都到齊了,出發幹下件事咯觸發

的确實作了線程等待其他線程完成的功能

注意觀察線程ID,可以發現每次觸發 barrierAction 屏障動作都是由最後一個線程來執行的