这俩工具太像了!到底啥时候用CountDownLatch,啥时候用CyclicBarrier?

软件求生 2025-04-23 09:21:34



哈喽,大家好鸭!

我是你们活泼、热爱技术、31岁依然活跃在一线开发岗位的小米!

今天咱们来聊个我最近社招面试被问懵的Java多线程面试题!是的,我!被问!懵!了!

故事从一场“社招二面”说起…

事情是这样的,前段时间我在一家大厂的Java社招面试现场,二面官看起来特别和蔼,开场就聊兴趣爱好、项目经验,气氛不要太好。

我心想:“稳了稳了,这波感觉我要拿Offer了!”

结果,突然他话锋一转:

“小米啊,那你说说看,CyclicBarrier 和 CountDownLatch 有啥区别?”

我当时脑子一懵:“啊?不都用来多线程同步的吗?好像谁用完了就释放谁吧……”

这就是传说中的,面试现场翻车事故现场警告。

回来后我疯狂补课,真香!

为了不给下一个自己挖坑,我决定,搞!清!楚!

我泡了一晚上的Java并发库,啃源码、写demo,终于明白了它俩的真正区别。今天就来跟大家讲清楚,包你看完不迷糊!

CountDownLatch 和 CyclicBarrier 各是什么?

咱先别上来就区别、应用场景,先搞清楚这俩是什么东西!别怕,我给你捋顺~

1、CountDownLatch —— 倒计时门闩

顾名思义,CountDownLatch 就是个倒计时的门闩。

当倒计时为 0,门闩打开,等待的线程就可以继续执行了。

核心方法:

await():等待,直到计数归零

countDown():计数器减 1

怎么理解呢?

比如我们去旅游,一群小伙伴约定好 “大家都到齐了再开车走”。

司机线程调用 await() 坐车等着。

每来一个人,countDown() 减 1。

直到所有人都到了,计数为 0,司机开车走人!

特点:

一次性:用完就废,下次得重新new

计数器不能重置

等待的是主线程或者某几个线程

2、CyclicBarrier —— 循环栅栏

CyclicBarrier 字面意思是循环的障碍物。

它是让一批线程都到达了障碍点,再一起继续执行。

核心方法:

await():线程调用此方法到达栅栏点,等待其他线程

可以设置回调 Runnable,当最后一个线程到达时执行

怎么理解呢?

比如跑接力赛,四个运动员要等所有人都到达起跑线,才一起开始跑。

大家站好位置(await())

等最后一个运动员到达,发令员(Runnable)说:“预备,跑!”

然后所有人一起冲刺!

特点:

可循环使用:用完可以重置,再来一轮

支持设置栅栏动作,所有线程到达后执行

同步的是一组线程彼此之间

形象对比图来咯!

小实验验证一下!

说了这么多,咱写点小Demo验证验证:

1、CountDownLatch 示例

运行结果:

2、CyclicBarrier 示例

运行结果:

典型应用场景对比

小米的独家记忆法!

为了防止以后再社死,我给自己总结了个超级好记忆方法,分享给你们

1、CountDownLatch → 倒计时门闩,等一批“完成通知”

门闩开了,其他线程/主线程才能过

2、CyclicBarrier → 回环栅栏,等一批“集合信号”

都站好了,才能一起开跑

一句话:

一个是主等子,一个是子等子

一个是一次性,一个是可循环

就记住这个,就能在面试上自信爆表啦!

面试官最后是这么总结的

我事后也问了那个面试官,他说:

“小米,其实你们日常用的少,但这种题就是看你理解同步机制、场景选择能力。项目中用不对,比不会更严重。”

听完我心里一紧——确实啊!

好在这次补了个扎实,未来再遇到多线程场景,也能更合理选型啦!

总结一下

END

写到这,突然有点感慨。

31岁,依然能在面试上学到新东西,说明技术这碗饭,真是吃一辈子学一辈子啊!

多线程是Java工程师的必备技能,不管是不是“用得少”,理解同步机制、选型得当,才是成熟开发者该有的样子。

如果这篇文章对你有帮助,点个【在看】或者【转发】支持一下小米叭!

有问题评论区留言,我们一起探讨!

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!

0 阅读:0

软件求生

简介:从事软件开发,分享“技术”、“运营”、“产品”等。