1. 程式人生 > >CyclicBarrier循環屏障相關

CyclicBarrier循環屏障相關

lai sta 參考 value 兩個 runnable public .net 得到

簡介

CyclicBarrier 的字面意思是可循環使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,直到最後一個線程到達屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續幹活。CyclicBarrier默認的構造方法是CyclicBarrier(int parties),其參數表示屏障攔截的線程數量,每個線程調用await方法告訴CyclicBarrier我已經到達了屏障,然後當前線程被阻塞。

實例代碼如下:

01 public class CyclicBarrierTest {
02
03 static CyclicBarrier c = new CyclicBarrier(2);
04
05 public static void main(String[] args) {
06 new Thread(new Runnable() {
07
08 @Override
09
public void run() {
10 try {
11 c.await();
12 } catch (Exception e) {
13
14 }
15 System.out.println(
1);
16 }
17 }).start();
18
19 try {
20 c.await();
21 } catch (Exception e) {
22
23 }
24 System.out.println(2);
25 }
26 }

輸出

1 2
2 1

或者輸出

1 1
2 2

如果把new CyclicBarrier(2)修改成new CyclicBarrier(3)則主線程和子線程會永遠等待,因為沒有第三個線程執行await方法,即沒有第三個線程到達屏障,所以之前到達屏障的兩個線程都不會繼續執行。

CyclicBarrier還提供一個更高級的構造函數CyclicBarrier(int parties, Runnable barrierAction),用於在線程到達屏障時,優先執行barrierAction,方便處理更復雜的業務場景。代碼如下:

01 public class CyclicBarrierTest2 {
02
03 static CyclicBarrier c = new CyclicBarrier(2, new A());
04
05 public static void main(String[] args) {
06 new Thread(new Runnable() {
07
08 @Override
09 public void run() {
10 try {
11 c.await();
12 } catch (Exception e) {
13
14 }
15 System.out.println(1);
16 }
17 }).start();
18
19 try {
20 c.await();
21 } catch (Exception e) {
22
23 }
24 System.out.println(2);
25 }
26
27 static class A implements Runnable {
28
29 @Override
30 public void run() {
31 System.out.println(3);
32 }
33
34 }
35
36 }

輸出

1 3
2 1
3 2

CyclicBarrier的應用場景

CyclicBarrier可以用於多線程計算數據,最後合並計算結果的應用場景。比如我們用一個Excel保存了用戶所有銀行流水,每個Sheet保存一個帳戶近一年的每筆銀行流水,現在需要統計用戶的日均銀行流水,先用多線程處理每個sheet裏的銀行流水,都執行完之後,得到每個sheet的日均銀行流水,最後,再用barrierAction用這些線程的計算結果,計算出整個Excel的日均銀行流水。

CyclicBarrier和CountDownLatch的區別

  • CountDownLatch的計數器只能使用一次。而CyclicBarrier的計數器可以使用reset() 方法重置。所以CyclicBarrier能處理更為復雜的業務場景,比如如果計算發生錯誤,可以重置計數器,並讓線程們重新執行一次。
  • CyclicBarrier還提供其他有用的方法,比如getNumberWaiting方法可以獲得CyclicBarrier阻塞的線程數量。isBroken方法用來知道阻塞的線程是否被中斷。比如以下代碼執行完之後會返回true。

isBroken的使用代碼如下:

01 import java.util.concurrent.BrokenBarrierException;
02 import java.util.concurrent.CyclicBarrier;
03
04 public class CyclicBarrierTest3 {
05
06 static CyclicBarrier c = new CyclicBarrier(2);
07
08 public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
09 Thread thread = new Thread(new Runnable() {
10
11 @Override
12 public void run() {
13 try {
14 c.await();
15 } catch (Exception e) {
16 }
17 }
18 });
19 thread.start();
20 thread.interrupt();
21 try {
22 c.await();
23 } catch (Exception e) {
24 System.out.println(c.isBroken());
25 }
26 }
27 }

輸出

true



參考鏈接:http://ifeve.com/concurrency-cyclicbarrier/
參考鏈接:https://blog.csdn.net/zzg1229059735/article/details/61191679

CyclicBarrier循環屏障相關