JVM自带的
在 Java 6 之后, synchronized 引入了大量的优化如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销,这些优化让 synchronized 锁的效率提升了很多。因此, synchronized 还是可以在实际项目中使用的,像 JDK 源码、很多开源框架都大量使用了 synchronized 。
关于偏向锁多补充一点:由于偏向锁增加了 JVM 的复杂性,同时也并没有为所有应用都带来性能提升。因此,在 JDK15 中,偏向锁被默认关闭(仍然可以使用 -XX:+UseBiasedLocking 启用偏向锁),在 JDK18 中,偏向锁已经被彻底废弃(无法通过命令行打开)。
基于对象监视器,在对象头中的mark word里
wait、notify也依赖对象监视器,因此,synchronized和wait、notify要配合使用
仅保障执行结果的有序性,而不保障指令重排序的有序性
关键字
monitorenter、monitorexit 实现修饰代码块
ACC_SYNCHRONIZED 实现修饰同步方法
均是基于 Monitor 实现的
Monitor (内部锁)
两个队列:
_WaitSet、_EntryList
_owner:
锁升级
偏向锁 -> 轻量级锁 -> 重量级锁
MarkWord 变化
偏向锁:(jdk18 中被废除)
markword中记录偏向的线程id
轻量级锁:
检测偏向线程id不是当前的线程,立即撤销
每个线程生成LockRecord ( LR ),并尝试自旋cas设置到markword中的线程id
重量级锁:(即 Monitor 的内部锁)
轻量级锁cas次数达到阈值 or 线程个数超过阈值,则升级到重量级锁
需要请求操作系统介入,内核管控
Synchronized 的锁优化
- 适应性自旋
即上面的自旋锁
- 锁消除
编译期的优化
- 锁粗化
应该 也是编译期的优化
参考文档:
1、https://javaguide.cn/java/concurrent/java-concurrent-questions-02.html#%E4%B9%90%E8%A7%82%E9%94%81%E5%AD%98%E5%9C%A8%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98
2、https://mp.weixin.qq.com/s/h3VIUyH9L0v14MrQJiiDbw