别再“报菜名“了,用一条逻辑链路带你搞定 Synchronized 和 Lock 的区别
别再"报菜名"了,用一条逻辑链路带你搞定 Synchronized 和 Lock 的区别
网上各种推文和博客都自说自话的的教人不要去背八股文,要去理解八股文,真要讲解起自己的内容了,又在自顾自的报菜名,把一堆离散的特性罗列出来,几乎没有逻辑性,想到哪一点说哪一点,就像这个八股文题目一样,至少能答出来五条.这五条每条都是分开的特性,没有内在联系,逻辑性也微乎其微,所以我以为,这种繁琐的八股文,首先要在最开始时就创建一条便于记忆的逻辑链路,不要太依赖于自己的离散记忆,这是不可靠且不稳定的(起码对我来说)
我觉得这种繁琐的八股文,最稳妥的方法是在最开始就创建一条便于记忆的逻辑链路。别依赖那种不稳定的离散记忆,咱得按锁的"一生"把这些点串起来。
-
先从语法切入(出身决定了怎么释放)
首先看出身。
synchronized是由 JVM 控制的关键字,而Lock是 JDK 层面的一个接口。因为出身不同,管理方式就变了:Synchronized既然是 JVM 管的,它就很智能,一旦代码出异常了,JVM 会自动帮你把锁给放了。Lock是 JDK 层面的,它是"人工"的,所以你得显式地去释放。通常都要写在finally块里手动执行unlock(),不然锁就死在那儿了。 -
核心特性(分配规则)
有了出身,再看它们的"性格",也就是公平性。
Synchronized比较霸道,它是非公平锁,新来的线程可以直接插队。Lock就很灵活,它既支持非公平锁,也支持公平锁(可以在构造的时候传参数实现)。 -
锁的使用周期(获取、唤醒、中断)
最后咱们看这个锁从"开始拿"到"中间等"再到"被唤醒"的整个操作逻辑,这才是最体现差距的地方:
锁的获取:
synchronized只有一种姿势,就是线程阻塞在那死等。而Lock可以通过tryLock进行非阻塞获取,拿不到我就干别的去,甚至还能设置个超时时间。锁的中断:
synchronized不支持中断,一旦等上了谁也劝不动。但Lock可以通过lockInterruptibly响应中断,等烦了是可以撤回的。锁的唤醒:
synchronized配合notify/notifyAll只能乱扣或者全喊。而Lock配合Condition可以实现精准唤醒,我想叫醒哪一类线程就叫醒哪一类。
更多推荐




所有评论(0)