CyclicBarrier 的字面意思是可循環(huán)使用(Cyclic)的屏障(Barrier)。它要做 的事情是,讓一組線程到達(dá)一個屏障(也可以叫同步點)時被阻塞,直到最后一 個線程到達(dá)屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續(xù)運行。
CyclicBarrier 默認(rèn)的構(gòu)造方法是 CyclicBarrier(intparties),其參數(shù)表示屏障攔截 的線程數(shù)量,每個線程調(diào)用 await 方法告訴 CyclicBarrier 我已經(jīng)到達(dá)了屏障,然 后當(dāng)前線程被阻塞。 CyclicBarrier 還提供一個更高級的構(gòu)造函數(shù) CyclicBarrier(intparties, Runnable barrierAction),用于在線程到達(dá)屏障時,優(yōu)先執(zhí)行 barrierAction,方便處理更復(fù) 雜的業(yè)務(wù)場景。 CyclicBarrier 可以用于多線程計算數(shù)據(jù),最后合并計算結(jié)果的場景。

CountDownLatch和CyclicBarrier辨析?
CountDownLatch 的計數(shù)器只能使用一次,而 CyclicBarrier 的計數(shù)器可以反復(fù)使用。?
CountDownLatch.await 一般阻塞工作線程,所有的進(jìn)行預(yù)備工作的線程執(zhí)行 countDown,而 CyclicBarrier 通過工作線程調(diào)用 await 從而自行阻塞,直到所有工 作線程達(dá)到指定屏障,再大家一起往下走。?
在控制多個線程同時運行上,CountDownLatch 可以不限線程數(shù)量,而 CyclicBarrier 是固定線程數(shù)。?
同時,CyclicBarrier 還可以提供一個 barrierAction,合并多線程計算結(jié)果。
public class CyclicBarrierDemo {
? ? static class TaskThread extends Thread {
? ? ? ? CyclicBarrier barrier;
? ? ? ? public TaskThread(CyclicBarrier barrier) {
? ? ? ? ? ? this.barrier = barrier;
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Thread.sleep(1000);
? ? ? ? ? ? ? ? System.out.println(getName() + " 到達(dá)柵欄 A");
? ? ? ? ? ? ? ? barrier.await();
? ? ? ? ? ? ? ? System.out.println(getName() + " 沖破柵欄 A");
? ? ? ? ? ? ? ? Thread.sleep(2000);
? ? ? ? ? ? ? ? System.out.println(getName() + " 到達(dá)柵欄 B");
? ? ? ? ? ? ? ? barrier.await();
? ? ? ? ? ? ? ? System.out.println(getName() + " 沖破柵欄 B");
? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? public static void main(String[] args) {
? ? ? ? int threadNum = 5;
? ? ? ? CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + " 完成最后任務(wù)");
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? for(int i = 0; i < threadNum; i++) {
? ? ? ? ? ? new TaskThread(barrier).start();
? ? ? ? }
? ? }
}
打印結(jié)果:
Thread-1 到達(dá)柵欄 A
Thread-3 到達(dá)柵欄 A
Thread-0 到達(dá)柵欄 A
Thread-4 到達(dá)柵欄 A
Thread-2 到達(dá)柵欄 A
Thread-2 完成最后任務(wù)
Thread-2 沖破柵欄 A
Thread-1 沖破柵欄 A
Thread-3 沖破柵欄 A
Thread-4 沖破柵欄 A
Thread-0 沖破柵欄 A
Thread-4 到達(dá)柵欄 B
Thread-0 到達(dá)柵欄 B
Thread-3 到達(dá)柵欄 B
Thread-2 到達(dá)柵欄 B
Thread-1 到達(dá)柵欄 B
Thread-1 完成最后任務(wù)
Thread-1 沖破柵欄 B
Thread-0 沖破柵欄 B
Thread-4 沖破柵欄 B
Thread-2 沖破柵欄 B
Thread-3 沖破柵欄 B
從打印結(jié)果可以看出,所有線程會等待全部線程到達(dá)柵欄之后才會繼續(xù)執(zhí)行,并且最后到達(dá)的線程會完成 Runnable 的任務(wù)。
CyclicBarrier 使用場景
可以用于多線程計算數(shù)據(jù),最后合并計算結(jié)果的場景。