1. CyclicBarrier 是什么强重?
從字面上的意思可以知道礼旅,這個類的中文意思是“循環(huán)柵欄”。大概的意思就是一個可循環(huán)利用的屏障俐东。
它的作用就是會讓所有線程都等待完成后才會繼續(xù)下一步行動跌穗。
舉個例子,就像生活中我們會約朋友們到某個餐廳一起吃飯虏辫,有些朋友可能會早到蚌吸,有些朋友可能會晚到,但是這個餐廳規(guī)定必須等到所有人到齊之后才會讓我們進(jìn)去砌庄。這里的朋友們就是各個線程羹唠,餐廳就是 CyclicBarrier。
2. 怎么使用 CyclicBarrier
2.1 構(gòu)造方法
public CyclicBarrier(int parties)
public CyclicBarrier(int parties, Runnable barrierAction)
解析:
- parties 是參與線程的個數(shù)
- 第二個構(gòu)造方法有一個 Runnable 參數(shù)娄昆,這個參數(shù)的意思是最后一個到達(dá)線程要做的任務(wù)
2.2 重要方法
public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
解析:
- 線程調(diào)用 await() 表示自己已經(jīng)到達(dá)柵欄
- BrokenBarrierException 表示柵欄已經(jīng)被破壞佩微,破壞的原因可能是其中一個線程 await() 時被中斷或者超時
2.3 基本使用
2.3.1 需求
一個線程組的線程需要等待所有線程完成任務(wù)后再繼續(xù)執(zhí)行下一次任務(wù)
2.3.2 代碼實現(xiàn)
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ù)。
3. CyclicBarrier 使用場景
可以用于多線程計算數(shù)據(jù)好爬,最后合并計算結(jié)果的場景扒俯。
4. CyclicBarrier 與 CountDownLatch 區(qū)別
- CountDownLatch 是一次性的奶卓,CyclicBarrier 是可循環(huán)利用的
- CountDownLatch 參與的線程的職責(zé)是不一樣的,有的在倒計時撼玄,有的在等待倒計時結(jié)束夺姑。CyclicBarrier 參與的線程職責(zé)是一樣的。
參考文章: