一、重量级锁和轻量级锁
重量级锁(悲观锁):synchronized,但是synchronized目前已经优化,即锁升级操作
轻量级锁(乐观锁):JUC、CAS
区别:重量级锁需要经过linux内核态完成,轻量级锁只需要在用户态完成
二、CAS (Compare And Swap)
在jvm底层是通过汇编指令:lock cpu 和cmpxchg实现,适用场景:临界区代码执行时间较短、抢占锁的线程不宜不太多
三、synchronized锁升级过程
不要适用String常量、Integer、Long等基础类型作为synchronized锁对象。synchronized只能保证原子性和可见性,不能保证重排序。volatile只能保证可见性和有序性,不能保证原子性
普通对象->偏向锁->轻量级锁->重量级锁
什么是偏向锁:偏向第一个持有该锁的线程,也就是如果没有竞争,只有一个线程A的场景下,该锁归属当前线程A。当出现另外一个线程B参与竞争,则升级为轻量级锁
偏向锁和轻量级锁:在用户态完成
重量级锁:在内核态完成
四、偏向锁
偏向锁默认是启动,通过参数 -XX:-UseBiasedLocking 进行关闭
偏向锁启动,jvm 4秒之后启动,由于jvm启动过程中会出现锁竞争,所以默认配置4s之后才开启,可以通过参数进行-XX:BiasedLockingStartupDelay=0
打开偏向锁一定会提升性能吗?不一定,因为多数情况下,是可预知,一定存在锁竞争,只要存在锁竞争就会进行所升级,那么就可直接跳过偏向锁这个状态。
五、轻量级锁升级为重量级锁
jdk 1.6以前:可以通过jvm调优进行设置
1)一个线程,自旋10次后升级为重量级锁
2)等待锁的线程总数 >= cpu核心数/2,升级为重量级锁
jdk 1.6以后,不需要调优了,jvm自己决定
六、synchronized底层实现
monitorenter、monitorexit两个指令