偏向锁、轻量级锁、重量级锁、synchronized、Lock、ReentrantLock、读写锁、自旋锁、乐观悲观锁,古风记忆,适配面试。
总起
并发多线程争疆场,资源抢夺起刀枪。 锁分乐观与悲观,轻重偏向各行藏。 隐显两套把门户,自旋忙等或眠藏。 取舍看清场景事,莫教死锁困四方。
一、悲观锁 vs 乐观锁
plaintext
悲观预设人来抢,上锁拒客守仓墙。 synchronized、ReentrantLock 归此壤。 乐观不信人相攘,版本号上辨兴亡。 冲突再做重试计,不加真锁性飞扬。 CAS为刃行其事,版本戳记辨沧桑。记忆:
- 悲观锁:默认一定会竞争,先上锁再干活;
- 乐观锁:默认没人抢,不加锁,CAS / 版本号检测冲突,失败重试。
二、synchronized(内置隐式锁)锁升级四态
无锁 → 偏向锁 → 轻量级锁 (自旋) → 重量级锁,只能升级,不能降级
plaintext
初来无锁本寻常,单线程启偏向章。 偏爱此线专相守,省去加锁往复忙。 多线相争冲突起,偏向褪去换轻装。 自旋循环空轮转,不肯休眠待曙光。 自旋耗尽CPU量,竞争激烈换重疆。 向OS借互斥量,线程阻塞入眠乡。 升级单向无归路,一旦沉渊难复扬。- 无锁:无竞争
- 偏向锁:单线程优先,消除 CAS 开销
- 轻量级锁:多线程交替,自旋,不阻塞,耗 CPU
- 重量级锁:内核互斥锁,线程阻塞挂起,耗上下文切换
口诀:单偏,交轻,争重重;只升不降不可逆
三、synchronized vs ReentrantLock
plaintext
synchronized隐式章,jvm之内铸铜墙。 自动上锁自动放,异常解锁不慌张。 不可中断非公平,功能朴素少锋芒。 ReentrantLock显式枪,手动开闭要谨详。 可中断来可公平,超时等待计时长。 条件队列多等待,功能繁复力刚强。 锁忘释放生危祸,finally内把锁偿。表格
| 要点诗意提炼 |
|---|
| synchronized:隐式、自动释放、不可中断、非公平、JVM 管控 |
| ReentrantLock:显式 lock/unlock,finally 释放;支持公平 / 非公平、可中断、超时、Condition |
四、读写锁 ReentrantReadWriteLock
plaintext
读多写少别匆忙,读写分锁各分疆。 读锁共享千客访,写锁独占守高墙。 读可同来写独往,写来读客尽潜藏。 警惕写锁饥饿患,久读无写祸根藏。记忆:读共享、写互斥;适合读多写少;会写饥饿。
五、自旋锁
plaintext
自旋不肯入眠床,循环轮询盼锁光。 少去切换上下文,CPU消耗暗自伤。 竞争微弱方可用,激烈场景不可扬。不阻塞,空循环等锁;竞争大 CPU 暴涨。
六、可重入锁
plaintext
同线再入旧锁堂,重入不把自身伤。 计数增减知进退,释放匹配莫相忘。 syn与Reentrant,二者皆具此所长。同一个线程可以多次获取同一把锁,计数器加减。
七、公平锁 & 非公平锁
plaintext
公平排队依次上,先来先得不越墙。 吞吐平平秩序稳。 非公闯锁不排岗,抢占先机意气扬。 吞吐量高是长处,线程饥饿暗中藏。 synchronized非公相,Lock可择两规章。- 公平:排队,FIFO,吞吐低
- 非公平:抢锁,不排队,吞吐高,可能饥饿
八、死锁四句
plaintext
互斥占有不释放,请求保持不肯降。 不可剥夺无退让,循环等待结成网。 四者齐聚死锁酿。死锁四大条件:互斥、请求并持有、不可剥夺、循环等待。
完整背诵七言诗
plaintext
并发争访起仓皇,乐观悲观两阵场。 悲观先锁防侵扰,乐观CAS辨兴亡。 syn隐锁jvm藏,四级升阶不可逆。 单线程处偏向启,交替相争轻量扬。 自旋耗尽竞争烈,重量级锁入眠乡。 ReentrantLock显锋芒,手动开闭要提防。 可中断还可超时,公平队列可裁量。 finally中释枷锁,遗忘释放祸难防。 读写分锁分疆场,读共写独理昭彰。 读多写少宜使用,写锁饥饿要提防。 自旋轮询不眠床,竞争微弱性能强。 重入计数同线进,公平非公细思量。 互斥持守难夺让,循环等待死锁殇。 选锁要看场景事,没有一锁胜八方。极简面试速记口诀
乐观 CAS,悲观上锁; syn 四态:无‑偏‑轻‑重,只升不降; syn 隐自动,Lock 显手动;可中断、公平、超时 Lock 强; 读共享,写独占,读写锁适配读多场景; 自旋耗 CPU,重入计数扛; 公平排队,非公抢占;四凑齐全死锁酿。