什么是 Java 的 CyclicBarrier(代碼示例)
你的回答(口語(yǔ)化,面試場(chǎng)景)
面試官:什么是 Java 的 CyclicBarrier?
你:
好的,我來(lái)舉個(gè)例子說(shuō)明。比如一個(gè)游戲需要5個(gè)玩家全部準(zhǔn)備就緒才能開(kāi)始,這時(shí)候可以用 CyclicBarrier。
核心作用CyclicBarrier 讓一組線程互相等待,直到所有線程都到達(dá)屏障點(diǎn)(Barrier),再一起繼續(xù)執(zhí)行。它像一道關(guān)卡,必須等所有線程到齊才能放行。
核心特性
- 可重復(fù)使用:所有線程通過(guò)屏障后,
CyclicBarrier會(huì)自動(dòng)重置(比如玩家結(jié)束一局后,可以開(kāi)始下一局)。 - 支持回調(diào):可以設(shè)置一個(gè)回調(diào)任務(wù)(Runnable),在所有線程到達(dá)屏障后觸發(fā)(比如發(fā)游戲開(kāi)始的廣播)。
- 使用場(chǎng)景
- 分階段任務(wù):多線程分批次處理數(shù)據(jù),等待所有線程完成第一階段后,再統(tǒng)一進(jìn)入第二階段。
- 壓測(cè)模擬:模擬1000個(gè)用戶同時(shí)發(fā)起請(qǐng)求(等所有線程就緒后同時(shí)觸發(fā))。
- 分布式協(xié)同:多個(gè)微服務(wù)節(jié)點(diǎn)完成初始化后,同時(shí)對(duì)外提供服務(wù)。
代碼示例
// 3個(gè)線程互相等待,全部到達(dá)后執(zhí)行回調(diào)
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有玩家已就位,游戲開(kāi)始!");
});
// 玩家線程
executor.submit(() -> {
System.out.println("玩家A準(zhǔn)備完成");
barrier.await(); // 等待其他玩家
System.out.println("玩家A開(kāi)始游戲");
});
// 類(lèi)似地提交玩家B、C的線程 對(duì)比 CountDownLatch
- 重置能力:
CyclicBarrier可重復(fù)用,CountDownLatch只能一次性。 - 觸發(fā)角色:
CyclicBarrier是線程互相等待,CountDownLatch是主線程等待子線程。
預(yù)測(cè)面試官可能的追問(wèn)及回答
追問(wèn)1:如果某個(gè)線程在 await() 時(shí)被中斷了,會(huì)發(fā)生什么?
回答:
- 被中斷的線程會(huì)拋出
InterruptedException,同時(shí)其他等待的線程會(huì)收到BrokenBarrierException,屏障會(huì)失效。 - 需要調(diào)用
reset()重置屏障后才能繼續(xù)使用。
追問(wèn)2:CyclicBarrier 底層是如何實(shí)現(xiàn)的?
回答:
- 基于
ReentrantLock和Condition。- 內(nèi)部維護(hù)一個(gè)計(jì)數(shù)器,線程調(diào)用
await()時(shí)計(jì)數(shù)器減1。 - 當(dāng)計(jì)數(shù)器歸零時(shí),觸發(fā)回調(diào)任務(wù),并喚醒所有等待線程。
- 內(nèi)部維護(hù)一個(gè)計(jì)數(shù)器,線程調(diào)用
知識(shí)框架與底層原理補(bǔ)充
核心機(jī)制
| 組件 | 作用 |
|---------------------|-------------------------------------------------------------------------|
| 屏障點(diǎn)(Barrier) | 線程必須等待其他線程到達(dá)的位置。 |
| Generation | 記錄當(dāng)前屏障的狀態(tài)(是否已破壞),支持重置后復(fù)用。 |
| 回調(diào)任務(wù) | 可選的 Runnable,由最后一個(gè)到達(dá)屏障的線程執(zhí)行。 |
源碼級(jí)實(shí)現(xiàn)邏輯
初始化:設(shè)置參與線程數(shù)(parties)和回調(diào)任務(wù)。
await() 流程:
- 獲取鎖(
ReentrantLock),檢查屏障是否已破壞(Broken)。 - 減少剩余計(jì)數(shù)(
count),若count == 0,執(zhí)行回調(diào)并喚醒所有線程。 - 若未歸零,線程通過(guò)
Condition.await()進(jìn)入等待隊(duì)列。
使用注意事項(xiàng)
- 獲取鎖(
ReentrantLock),檢查屏障是否已破壞(Broken)。 - 減少剩余計(jì)數(shù)(
count),若count == 0,執(zhí)行回調(diào)并喚醒所有線程。 - 若未歸零,線程通過(guò)
Condition.await()進(jìn)入等待隊(duì)列。
實(shí)戰(zhàn)案例
- 場(chǎng)景:電商大促時(shí),統(tǒng)計(jì)各區(qū)域銷(xiāo)量并匯總。
- 方案:
創(chuàng)建 CyclicBarrier,線程數(shù)與區(qū)域數(shù)相同。
每個(gè)線程計(jì)算一個(gè)區(qū)域的銷(xiāo)量,完成后調(diào)用 await()。
所有線程到達(dá)后,觸發(fā)回調(diào)任務(wù)匯總總銷(xiāo)量。
CyclicBarrier barrier = new CyclicBarrier(4, () -> {
System.out.println("全部區(qū)域銷(xiāo)量計(jì)算完成,總銷(xiāo)量:" + total);
});
// 4個(gè)區(qū)域計(jì)算線程
for (int i = 0; i < 4; i++) {
executor.submit(() -> {
calculateRegionSales();
barrier.await();
});
} 總結(jié)
- CyclicBarrier 是多線程協(xié)同的利器,適合需要多次同步的場(chǎng)景(如分階段任務(wù))。
- 理解底層鎖機(jī)制和異常處理,避免因線程中斷導(dǎo)致屏障失效。
- 優(yōu)先于 CountDownLatch 的場(chǎng)景:需重復(fù)觸發(fā)同步點(diǎn),或需要回調(diào)任務(wù)統(tǒng)一處理結(jié)果。
到此這篇關(guān)于什么是 Java 的 CyclicBarrier的文章就介紹到這了,更多相關(guān)Java 的 CyclicBarrier內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot訪問(wèn)靜態(tài)資源遇到的坑及解決
這篇文章主要介紹了springboot訪問(wèn)靜態(tài)資源遇到的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Java對(duì)zip,rar,7z文件帶密碼解壓實(shí)例詳解
在日常業(yè)務(wù)中,會(huì)遇到一些瑣碎文件需要打包到一個(gè)壓縮包中上傳,業(yè)務(wù)方在后臺(tái)接收到壓縮包后自行解壓,然后解析相應(yīng)文件。而且可能涉及安全保密,因此會(huì)在壓縮時(shí)帶上密碼,要求后臺(tái)業(yè)務(wù)可以指定密碼進(jìn)行解壓。本文將用Java解決這一問(wèn)題,需要的可以參考一下2022-07-07
Spring Boot Rest控制器單元測(cè)試過(guò)程解析
這篇文章主要介紹了Spring Boot Rest控制器單元測(cè)試過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Java泛型模擬scala實(shí)現(xiàn)自定義ArrayList方式
這篇文章主要介紹了Java泛型模擬scala實(shí)現(xiàn)自定義ArrayList方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
踩坑之spring事務(wù),非事務(wù)方法與事務(wù)方法執(zhí)行相互調(diào)用方式
這篇文章主要介紹了踩坑之spring事務(wù),非事務(wù)方法與事務(wù)方法執(zhí)行相互調(diào)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
詳細(xì)聊聊Spring MVC重定向與轉(zhuǎn)發(fā)
大家應(yīng)該都知道請(qǐng)求重定向和請(qǐng)求轉(zhuǎn)發(fā)都是web開(kāi)發(fā)中資源跳轉(zhuǎn)的方式,這篇文章主要給大家介紹了關(guān)于Spring MVC重定向與轉(zhuǎn)發(fā)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09

