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 屏障動作都是由最後一個線程來執行的