雪花算法的自增序列,使用了 synchronized、AtomicLong、LongAdder 实现同步自增。
测试3个场景:
可以发现 synchronized 在单线程场景表现优秀,JDK6 对 synchronized 做了一系列优化。
锁消除
JVM检测到一些同步的代码块,完全不存在数据竞争的场景,也就是不需要加锁,就会进行锁消除
锁粗化
有很多操作都是对同一个对象进行加锁,就会把锁的同步范围扩展到整个操作序列之外
锁升级
根据并发度,提升锁的强度:偏向锁、轻量锁、重量锁
只有一个线程执行同步代码,线程不会主动释放偏向锁。
多个线程交替执行同步代码,线程尝试自旋获取锁,失败一定次数后(JVM控制,自适应)把锁升级为重量锁。
多个线程同时执行同步代码,阻塞取锁失败的线程。ObjectMonitor 有3个重要属性:EntryList、WaitSet、Owner。
偏向锁在单线程场景下,连 CAS 都用不上,效率当然快。
轻量锁通过自旋的方式提升效率,因为 LWP 阻塞、唤醒需要上下文切换,代价很大。
网络关于 synchronized 实现原理大多只是重量锁的实现,其中所谓监控对象就是 ObjectMonitor,源码位于 src\share\vm\runtime\objectMonitor.hpp。
面试中 synchronized 还可以展开问 对象头、栈帧、ReentrantLock,所以高频是有道理的。
原文:https://www.cnblogs.com/mougg/p/13983181.html