首頁 > 軟體

Java多執行緒CyclicBarrier的實現程式碼

2022-02-17 16:01:29

介紹

CyclicBarrier允許一組執行緒在到達某個柵欄點(common barrier point)互相等待,直到最後一個執行緒到達柵欄點,柵欄才會開啟,處於阻塞狀態的執行緒恢復繼續執行。

1.就比如說我們在打王者的時候,十個人必須全部載入到100%,才可以開局。否則只要有一個人沒有載入到100%,那這個遊戲就不能開始。先載入完成的玩家必須等待最後一個玩家載入成功才可以。

2.你可以想象長途客車,就算你是第一個上車的人,也要等待車滿才可以發車。否則車上所有人都要等待。

3.在百米賽跑裡,比賽沒開始之前,每個運動員都在賽場上自由活動,有的熱身,有的喝水,有的跟教練談論。比賽快開始時,準備完畢的運動員就預備在起跑線上,如果有個運動員還沒準備完(除去特殊情況),他們就一直等,直到運動員都在起跑線上,裁判喊口號後再開始跑。這裡的起跑線就是屏障,做完準備工作的運動員都等在起跑線,直到其他運動員也把準備工作做完。

程式碼介紹

接下來我們看看CyclicBarrier它的構造器

//構造器1
public CyclicBarrier(int parties, Runnable barrierAction) {
  if (parties <= 0) throw new IllegalArgumentException();
  this.parties = parties;
  this.count = parties;
  this.barrierCommand = barrierAction;
}
 
//構造器2
public CyclicBarrier(int parties) {
  this(parties, null);
}

CyclicBarrier有兩個構造器,第一個構造器是它的核心構造器

引數1: 在這裡你可以指定本局遊戲的參與者數量(要攔截的執行緒數)

引數2: 本局結束時要執行的任務,(也就是所有執行緒執行完後執行的執行緒)

CyclicBarrier供了兩種等待的方法,分別是定時等待和非定時等待。
引數1 : timeout 時間 , 引數2: 時間單位 TimeUnit.SECONDS (秒)

//非定時等待 (比如指定3個執行緒 每一個執行緒呼叫一次內部count--  當count==0時 釋放3個執行緒 然後count重置為3  )
public int await() throws InterruptedException, BrokenBarrierException {
  try {
    return dowait(false, 0L);
  } catch (TimeoutException toe) {
    throw new Error(toe);
  }
}
 
//定時等待 (就是子一定時間內如果還沒有 到時間自動喚醒)
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException {
  return dowait(true, unit.toNanos(timeout));
}

重置屏障
將屏障重置到初始狀態。 如果任何一方目前正在barrier處等待,他們將返回一個BrokenBarrierException。 注意,由於其他原因發生破損後復位可能會比較複雜; 執行緒需要以其他方式重新同步,然後選擇一個執行重置。 最好是為以後的使用建立一個新的障礙。

public void reset() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            breakBarrier();   // break the current generation
            nextGeneration(); // start a new generation
        } finally {
            lock.unlock();
        }
    }

案例:王者榮耀遊戲載入

public static void main(String[] args) throws InterruptedException {

        //設定這局遊戲的唯一id 和人數
        CyclicBarrierUtils.initialize("da1",10,()->{
            System.out.println("10人都載入完畢,進入遊戲");
        });
        //開始載入遊戲
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            ExecutorUtils.create(()->{
                System.out.println(finalI +":載入完畢,等待其他人....");
                CyclicBarrierUtils.await("da1");
            });
        }
    }

程式碼經過二次封裝,所以看看邏輯就行

如有侵權,請私信聯絡我

到此這篇關於Java多執行緒CyclicBarrier的文章就介紹到這了,更多相關Java多執行緒CyclicBarrier內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com