1.步骤
无锁->偏向锁->轻量级锁->重量级锁
2.原因
第一步:无锁
现在有一个共享资源,还没有线程拥有它呢,所以也就不加锁,所以现在就是无锁状态
第二步:轻量级锁
这时候,来了一个线程A,尝试获取这个资源(假设这个资源里面有对象,对象的字段,方法等),获取到了之后,会在获取到的这个对象的头中有一个叫mark word里面设置这个线程的id,也就是说此时只有它得到了这些资源,这个就是偏向锁
第三步:轻量级锁
这时候,又来了个线程B,想获取这个资源,此时JVM是这么做的
先把这把锁撤销,也就是JVM会暂停用有这把锁的线程,并撤销偏向锁,并且清除对象头的mark word的偏向状态,恢复到无锁状态,这时候也就是说线程A和B都开始竞争这个资源了,于是这时候锁就升级成轻量级锁了,然后他俩都通过CAS的方式获取到这把锁,谁先获取到谁就拥有资源,然后线程B开始自旋,如果在自旋的期间,线程A释放锁了,那么线程B就拿到了,就不用升级成重量级锁了,因为它的主人A不要它了,它要找下一个主人了
第四步:重量级锁
这时候假如又来了一堆线程,比如线程C、D、E、F、G、H…,然后想获取到这把锁,发现它已经有主人了,于是就自旋,此时线程B也在自旋想获取到这把锁,但是它们都没成功获取到这把锁,而这把锁感知到除了自己的主人有它之外,还有人想抢它,但是它不想跟别人走,于是就把自己升级成重量级锁。
3.synchronized的自旋
首先,它不是固定的自旋次数,它是自适应自旋次数,也就是一个动态改变的值,这个值会根据前一次自旋获取锁的状态来决定这次自旋的次数。
例如:上一次自旋成功了,则线程认为这次自旋也能成功,所以就多自旋几次,如果上次自旋失败了,就认为这次也失败,所以为了避免资源浪费,就减少自旋次数,来提高程序的执行效率。