Java執行緒池之柵欄
阿新 • • 發佈:2018-12-22
通過閉鎖來啟動一組相關的操作,或者等待一組相關的操作結束。閉鎖是一次性物件,一旦進入終止狀態,就不能重置。
柵欄類似於閉鎖,它能阻塞到一組執行緒到某個事件發生。柵欄於閉鎖的關鍵區別在於,所有執行緒必須同時到達柵欄位置,才能繼續執行。閉鎖用於等待事件,而柵欄用於等待其他執行緒。柵欄用於實現一些協議,例如幾個家庭決定在某個地方集合:”所有人6:00在麥當勞碰頭,到了以後要等待其他人,之後再討論下一步要做的事情。“
CyclicBarrier
可以使一定數量的參與方法反覆地在柵欄位置彙集,它在並行迭代演算法中非常有用:這種演算法通常將一個問題拆分成一系列獨立的子問題。當執行緒到達柵欄位置時將呼叫await
await
的呼叫超時,或者await
阻塞的執行緒被中斷,那麼柵欄將被認為是打破了,所有阻塞的await
呼叫都將終止並丟擲BrokenBarrierException
。如果成功通過柵欄那麼將為每個執行緒返回一個唯一的到達索引號,我們可以利用這些索引號來“選舉”產生一個領導執行緒,並在下一波迭代中由該領導執行緒執行一些特殊化的工作。CyclicBarrier
還可以使你將一個柵欄操作傳遞給建構函式,這是一個Runnable,當成功通過柵欄時會(在一個子執行緒中)執行它,但在阻塞執行緒被釋放之前是不能執行的。public static void main(String args[]) throws InterruptedException {
ExecutorService executors = Executors.newFixedThreadPool(10);
CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new Runnable() {
@Override
public void run() {//釋放柵欄時呼叫,也就是最後一個執行完畢的執行緒呼叫
System. out.println(Thread.currentThread().getName() + "釋放所有執行緒");
}
});
for (int i = 0; i < 10; i++) {
executors.submit(new CycRunnable(cyclicBarrier));
}
System.out.println("執行完畢");
}
private static class CycRunnable implements Runnable {
private CyclicBarrier cyclicBarrier;
public CycRunnable(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "開始執行:");
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "執行完畢並且等待");
cyclicBarrier.await();
System.out.println(Thread.currentThread().getName() + "等待結束");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
**注意:**如果執行緒數大於傳入給CyclicBarrier 的值,則多餘執行緒會一直等待,如果小於則所有執行緒會一直等待,CyclicBarrier 也無法釋放。
柵欄還有另外一種形式,那就是Exchanger
,它是一種兩方柵欄,各方在柵欄位置交換資料。當兩方執行不對稱的操作時,Exchanger會非常有用,例如當一個執行緒向緩衝區寫入資料,而另外一個執行緒從緩衝區中讀取資料。這些執行緒可以使用Exchanger來匯合,並將滿的緩衝區與空的緩衝區交換。當兩個執行緒通過Exchanger交換物件時,這種交換就把這兩個物件安全的交給釋出給另一方。
資料交換的時機取決於應用程式的響應需求。最簡單的方案是,當緩衝區被填滿時,由填充任務進行交換,當緩衝區為空時,由清空任務進行交換。這樣會把需要交換的次數降至最低,但如果新資料的到達率不可預測,那麼一些資料的處理過程就會延遲。另外一個方法是,不僅當緩衝區被填滿時進行交換,並且當緩衝區被填充到一定程度並保持一定時間後,也進行交換。