CyclicBarrier-循環柵欄
線程到達柵欄時調用await方法被阻塞,只有線程數據達到柵欄設置的閾值時,柵欄放行,所有線程繼續執行,此輪結束,柵欄進入下一輪。
案例:3個線程等待柵欄放行
Task
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Task implements Runnable{
private CyclicBarrier cyclicBarrier;
public Task(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "準備就緒");
cyclicBarrier.await();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "中斷了......");
} catch (BrokenBarrierException e) {
System.out.println(Thread.currentThread().getName() + "拋出損壞異常....");
}
}
}
啓動文件
import java.util.concurrent.CyclicBarrier;
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("主線程開始......");
CyclicBarrier cb = new CyclicBarrier(3, new Runnable(){
@Override
public void run() {
System.out.println("子線程全部就位,開始執行制定任務......");
}
});
Thread t1 = new Thread(new Task(cb), "Thread-1");
Thread t2 = new Thread(new Task(cb), "Thread-2");
Thread t3 = new Thread(new Task(cb), "Thread-3");
t1.start();
t2.start();
t3.start();
Thread.sleep(2000);
System.out.println("主線程執行完畢");
}
}
結果:
CyclicBarrier的異常
CyclicBarrier如果不能滿足閾值,超時或者等待的線程被中斷了,則所有等待線程都會拋出損壞異常,然後進入下一輪。
案例:損壞異常,假設閾值爲4,已經有3個線程等待,其中一箇中斷。
Task代碼不變
啓動文件修改
import java.util.concurrent.CyclicBarrier;
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("主線程開始......");
CyclicBarrier cb = new CyclicBarrier(4, new Runnable(){
@Override
public void run() {
System.out.println("子線程全部就位,開始執行制定任務......");
}
});
Thread t1 = new Thread(new Task(cb), "Thread-1");
Thread t2 = new Thread(new Task(cb), "Thread-2");
Thread t3 = new Thread(new Task(cb), "Thread-3");
t1.start();
t2.start();
t3.start();
Thread.sleep(1000);
t1.interrupt();
Thread.sleep(2000);
System.out.println("主線程執行完畢");
}
}
結果:
源碼分析:
CyclicBarrier基於ReentrantLock和Condition實現鎖機制。
成員變量
await方法:
breakBarrier損壞方法: