锁的4中状态:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态(级别从低到高)
偏向锁
-
偏向锁是默认开启的,但是是延迟的就是对象创建后,要过几秒才会修改为偏向锁。可以通过jvm参数设置为不延迟:-xx:BiasedLockingStartupDelay =0
-
偏向锁,锁对象的mark word 记录的是 线程ID 而不是monitor地址了。
-
偏向锁是指当一段同步代码一直被同一个线程所访问时,即不存在多个线程的竞争时,那么该线程在后续访问时便会自动获得锁,从而降低获取锁带来的消耗,即提高性能
-
偏向锁在 JDK 6 及之后版本的 JVM 里是默认启用的。可以通过 JVM 参数关闭偏向锁:-XX:-UseBiasedLocking(use前的-代表关闭,+代表打开),关闭之后程序默认会进入轻量级锁状态。
-
偏向锁的撤销(该锁对象以后都不能再使用偏向锁):
- 锁对象调用hashcode()方法
- 锁对象被一个以上线程使用
- 获取锁对象的线程使用wait/notify -->(直接升级为重量级锁)
-
(批量重定向)偏向锁从新偏向的条件:当程序中连续发生20次偏向锁撤销时,以后的就不会发生偏向锁撤销了,改为偏向锁重偏向了。
-
(批量撤销)当偏向锁的撤销连续发生40次后,以后程序中的所有对象都禁用偏向锁机制。
轻量级锁
-
一个锁对象被多个线程访问,但是不是同时访问,是a访问完了其他线程再访问也就是没有发生竞争的情况下,我们可以使用轻量级锁。
-
轻量级锁对我们使用中来说是透明的,语法仍然是synchronized
-
锁重入
重量级锁
- 锁膨胀(轻量级锁 变为重量级锁)
- 第一个线程还持有着轻量级锁对象时,这时第二个线程也需要对象锁,这时发生竞争。轻量级锁膨胀为重量级锁。此时锁对象会申请Monitor锁。并且第二个线程 加入到Monitor的EntryList对列中
- 自旋优化