90% 的人都答不全:Synchronized vs ReentrantLock
90% 的人都答不全:Synchronized vs ReentrantLock
咱们今天聊点轻松又带点血腥的故事——Java 里最八卦的两位“锁王”:synchronized 和 ReentrantLock。别急着说你都懂,面试官让我现场写出区别时,我脑袋嗡地一声,嘴里只飘出来 “加锁… 解锁… 可重入… 线程安全…” 这几个词,瞬间变成人工智能。
其实呢,这对“老冤家”我最早知道还是在公司老刘的茶水间八卦里——“哎你知道吗?synchronized 像老派班长,啥事都亲力亲为;ReentrantLock 就像业务经理,啥功能都能加插件”。当时我嘴上嗯嗯,其实心里一团浆糊。结果当天晚上就碰上一堆线程同步的锅!
后来忙着赶项目,有那么几次,我抱着试试看的心态把 synchronized 换成了 ReentrantLock,想着有了超能力。结果是——嗯,踩到的坑比想象中还多。
踩坑瞬间
印象最深,一次接口压力大,代码里逻辑是这样的:
lock.lock();
// ……疯狂的业务代码
lock.unlock();
我暗自窃喜,这回不会死锁吧?结果应用宕机,线程堆栈一看,傻眼——死锁!为啥?原来 try-finally 才是官方标配,我 unlock 写漏了。
再说回 synchronized(老班长风采):
synchronized (obj) {
// ……内部算法
}
安全是真安全,谁都跑不了。但有个痛——没法提前释放锁,更没有 tryLock,只有老实人一条路!更别说什么公平锁、可中断、条件队列这些骚操作了。
总结下常见“掉坑”片段:
- 用 lock 手滑没 unlock,就等着被锁死;
- synchronized 想灵活点,连窗都没有;
- 有些场景想要“等一会再干别的”,只有 ReentrantLock 顶得住。
不小心get到的点
偷懒总结下,两位锁王差得可不止一星半点:
| 特性 | synchronized | ReentrantLock |
|---|---|---|
| 可重入性 | ✔️ | ✔️ |
| 公平锁 | ❌ | ✔️ |
| 可中断 | ❌ | ✔️ |
| 超时等待 | ❌ | ✔️ |
| 条件队列 | ❌ | ✔️(newCondition) |
| 自动解锁 | ✔️(自动) | ❌(手动) |
synchronized 虽然老实,胜在简洁靠谱;ReentrantLock 妙就妙在你想怎么玩都给你接口,但姿势太多也容易自爆(比如 tryLock、lockInterruptibly、条件队列……)。
经验启示
几个八卦后的血泪教训:
- 简单的锁就用 synchronized,别装X,省时省力;
- 想玩骚操作(比如定时、可中断、公平)就用 ReentrantLock;
- 记得 lock 和 unlock 要成双成对,不要手滑——有 try-finally 病免疫;
- 不要迷信“某某锁性能好”,压测服众最重要;
- 代码审查时多催同事补 catch 和 unlock,基本靠人品不靠谱……
你以为这两招能包打天下?大错特错,JDK 新锁、StampedLock、读写锁还有一堆八卦在后面等着咱们。总算写完,下次再水点新故事 —— 收!
朋友们,其实锁的世界很大,“用对场景,保持谦逊”,才是真理。跑路嗑瓜子去了。
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章