哈喽,大家好鸭!
我是你们活泼、热爱技术、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 → 回环栅栏,等一批“集合信号”
都站好了,才能一起开跑
一句话:
一个是主等子,一个是子等子
一个是一次性,一个是可循环
就记住这个,就能在面试上自信爆表啦!
面试官最后是这么总结的我事后也问了那个面试官,他说:
“小米,其实你们日常用的少,但这种题就是看你理解同步机制、场景选择能力。项目中用不对,比不会更严重。”
听完我心里一紧——确实啊!
好在这次补了个扎实,未来再遇到多线程场景,也能更合理选型啦!
总结一下写到这,突然有点感慨。
31岁,依然能在面试上学到新东西,说明技术这碗饭,真是吃一辈子学一辈子啊!
多线程是Java工程师的必备技能,不管是不是“用得少”,理解同步机制、选型得当,才是成熟开发者该有的样子。
如果这篇文章对你有帮助,点个【在看】或者【转发】支持一下小米叭!
有问题评论区留言,我们一起探讨!
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!