當(dāng)面試官問(wèn)你Synchronized和ReentrantLock有什么區(qū)別?建議把這篇摔他臉上
在多線程編程的江湖中,鎖機(jī)制就是維護(hù)秩序的金科玉律。今天我們就來(lái)聊聊Java中兩大鎖界頂流——Synchronized與ReentrantLock的恩怨情仇,以及為什么江湖傳聞"公平鎖是性能殺手"。
1.兩位鎖界大佬的身世之謎
血統(tǒng)差異
- Synchronized:根正苗紅的Java元老(JDK1.0),以關(guān)鍵字形式直接嵌入語(yǔ)言體系
- ReentrantLock:JUC包(java.util.concurrent)新貴(JDK5.0),基于AQS實(shí)現(xiàn)的API式鎖
使用姿勢(shì)對(duì)比
// Synchronized的儀式感
synchronized(obj) {
// 臨界區(qū)代碼
}
// ReentrantLock的儀式感
Lock lock = new ReentrantLock();
lock.lock();
try {
// 臨界區(qū)代碼
} finally {
lock.unlock();
}
2.Synchronized VS ReentrantLock
功能對(duì)決表
特性 | Synchronized | ReentrantLock |
鎖獲取方式 | 隱式 | 顯式 |
可中斷 | ? | ? lockInterruptibly |
超時(shí)機(jī)制 | ? | ?tryLock |
公平鎖 | ? | ? |
條件變量 | 單個(gè) | 多個(gè) |
鎖釋放 | 自動(dòng) | 必須手動(dòng) |
隱藏技能解析
- 鎖粒度:ReentrantLock可實(shí)現(xiàn)更細(xì)粒度的控制(如不同條件變量)
- 性能差異:JDK6后synchronized優(yōu)化后旗鼓相當(dāng),但在高并發(fā)場(chǎng)景下ReentrantLock更勝一籌
- 死鎖逃生:tryLock可設(shè)置超時(shí)時(shí)間,避免永久等待
3.公平鎖的潘多拉魔盒
公平鎖的代價(jià)(示例代碼)
// 公平鎖版(性能殺手)
ReentrantLock fairLock = new ReentrantLock(true);
// 非公平鎖版(推薦姿勢(shì))
ReentrantLock unfairLock = new ReentrantLock();
為什么慎用公平鎖?
- 性能陷阱:維護(hù)FIFO隊(duì)列導(dǎo)致吞吐量下降30%-50%
- 線程喚醒開(kāi)銷:每次喚醒都要進(jìn)行上下文切換
- 偽公平現(xiàn)象:非公平鎖實(shí)際也能保證基本公平性
- 饑餓假象:現(xiàn)代操作系統(tǒng)調(diào)度機(jī)制已有效避免長(zhǎng)期饑餓
公平鎖存活指南(適用場(chǎng)景)
- 任務(wù)執(zhí)行時(shí)間差異巨大(毫秒級(jí) vs 秒級(jí))
- 必須嚴(yán)格保證先到先得(如證券交易系統(tǒng))
- 防止資源饑餓的極端場(chǎng)景
4.選鎖心法口訣
默認(rèn)選擇:能用synchronized就不用ReentrantLock
升級(jí)條件:遇到鎖分離、鎖投票等高級(jí)需求時(shí)再切換
公平警訓(xùn):非公平鎖能滿足90%場(chǎng)景,使用公平鎖需書面審批
防死守則:使用try-finally保證鎖釋放,避免鎖泄漏
5.小結(jié)
江湖傳言:"過(guò)早優(yōu)化是萬(wàn)惡之源"。選擇鎖機(jī)制時(shí)要遵循KISS原則(Keep It Simple, Stupid),在簡(jiǎn)潔與功能之間找到最佳平衡點(diǎn),方能在多線程的江湖中立于不敗之地。