1. 程式人生 > >Java CyclicBarrier 淺談

Java CyclicBarrier 淺談

strong 離開 nts 構造函數 fixed AS 修改 i++ play

CyclicBarrier 意思是柵欄, 可以讓多組線程到達某個點後開始等待, 等指定的線程數量都到達後再恢復線程, 這個CyclicBarrier是可以循環使用的. 又稱為循環柵欄.

栗子:

public class BarrierDemo {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(5);
        final CyclicBarrier barrier = new CyclicBarrier(5);
        
for (int i = 0; i < 5; i++) { service.execute(new Player("玩家" + i, barrier)); } service.shutdown(); } } public class Player implements Runnable { private final String name; private final CyclicBarrier barrier; public Player(String name, CyclicBarrier barrier) {
this.name = name; this.barrier = barrier; } public void run() { try { TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(3))); System.out.println(name + "已準備,等待其他玩家準備..."); barrier.await(); TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(3))); System.out.println(name
+ "已加入遊戲"); } catch (InterruptedException e) { System.out.println(name + "離開遊戲"); } catch (BrokenBarrierException e) { System.out.println(name + "離開遊戲"); } } }

CyclicBarrier 有兩個構造函數:

public CyclicBarrier(int parties)
public CyclicBarrier(int parties, Runnable barrierAction)

參數parties指定線程數量,當指定的線程值都到達柵欄點時,柵欄打開,線程恢復。需要註意的是,當指定的線程數量大於啟動的線程數量,比如修改上例中的代碼,只啟動9個線程,那麽所有的線程將一直處於等待狀態。第二種情況是指定的線程數量小於啟動的線程,上例代碼,啟動11個線程,那麽當第十個線程到達柵欄點時,那麽這十個線程就會恢復繼續執行,而第十一個線程將一直處於阻塞狀態。

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

CyclicBarrier的方法:

1. await() 使用該方法可以使得當前線程在柵欄點處進行阻塞, 等待所有線程.

2. await(long timeout, TimeUnit unit) 增加timeout參數, 等待超時後會拋出異常.

3. getNumberWaiting() 返回當前在柵欄處等待的參與者數目。此方法主要用於調試和斷言。

4. getParties() 該方法可以獲得構造函數中指定的需要在柵欄點阻塞的線程數量

Java CyclicBarrier 淺談