synchronized的锁升级过程 :
锁的状态总共有四种,级别由低到高依次为:无锁、偏向锁、轻量级锁、重量级锁
在 JDK 1.6之前,synchronized 还是一个重量级锁,是一个效率比较低下的锁,但是在JDK 1.6后,Jvm为了提高锁的获取与释放效率对(synchronized )进行了优化,引入了 偏向锁 和 轻量级锁 ,从此以后锁的状态就有了四种(无锁、偏向锁、轻量级锁、重量级锁),并且四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,即不可降级,也就是说只能进行锁升级
synchronized加锁锁的对象就是说在对象头中修改mark word的信息来实现的加锁,谁修改成功谁获得锁
上图中,如果对象最后2bit是00代表轻量级锁,如果是10代表重量级锁,11代表这个对象正在被GC回收,01有二种状态,再01的前提下,看倒数第三位0代表无锁,1代表是偏向锁
偏向锁和轻量级锁都是用户态级别的锁,不需要经过系统调用的过程,所以效率会高
偏向锁: 再执行的过程中只有一个线程执行,没有发生锁的竞争,直接将线程指针写入到对象的markeword中
当又来了一个线程(发生了竞争),会将偏向锁撤销,然后进行竞争,每个线程都有自己的线程栈,每个人再自己的线程内部生成LR(锁记录),然后用自旋的方式将自己的lr指针写入到对象的markeword中,当对象markword中指向了那个线程的lr,那个线程争抢成功,另一个线程会继续cas的去竞争,当竞争成功的线程执行完了,这个线程继续执行,这个时候就是轻量级锁
重量级锁; 发生竞争但是在自旋过程中依然没有获取到锁就会升级重量级锁,这种锁 需要经过一次系统调用,要上操作系统申请
为什么有自旋还需要重量级呢? 因为自旋是需要消耗cpu资源的 自旋时间太长会浪费cpu资源 重量级锁有等待队列,将线程放入等待队列,不需要消耗cpu资源
自旋几次呢? 默认是10次(可以设置)或者自旋线程数超过了cpu核数的一半,但是在jdk1.6进行了优化,自旋次数变成了自适应的,所以不用去设置
jvm再启动过程中,会有很多线程启动,所以jvm刚启动的时候,偏向锁不会打开,这时候创建的对象加锁会直接进入轻量级锁, 默认时间4秒后启动 可以设置 参数可以百度一下
刚new的对象如果偏向锁没有启动,就是普通对象,如果偏向锁启动就是匿名偏向锁
匿名偏向锁: 当偏向锁启动后才new的对象,但是没有线程去更改这个对象的markeword,所以线程指针为null, 这就叫匿名偏向锁
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)