synchronized实现解析
Posted 水田如雅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized实现解析相关的知识,希望对你有一定的参考价值。
JVM层的实现
对于代码:
int dataV = 1;
public synchronized void changeData()
dataV++;
public void readData()
synchronized (this)
System.out.println(dataV);
同步代码块
首先来看代码块方法readData
反编译之后:
对于同步代码快,反编译之后会生成成对的monitorenter
和monitorexit
。在执行monitorenter指令的时候,首先尝试获取对象的锁,如果这个锁没有被锁定或者当前线程已经拥有了那个对象的锁,锁的计数器就加1,在执行monitorexit指令时会将锁的计数器减1,当减为0的时候就释放锁。如果获取对象锁一直失败,那当前线程就要阻塞等待,直到对象锁被另一个线程释放为止。
同步方法
对于同步方法,反编译之后,发现多出来ACC_SYNCHRONIZED
;
当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象。
synchronized 的加锁优化
锁升级
synchronized 底层在openjdk中的实现,是使用monitor对象,通过等待通知机制,实现线程依次获取monitor。
但是这种加锁方式比较重,所以加入了锁升级的策略去通过逐步加锁,即偏向锁->轻量级锁->重量级锁,当出现竞争时候,去做做锁升级,例如,当只有一个线程去获取资源时候,最开始使用的是偏向锁,会在锁对象头里面填入使用的是偏向锁,和线程id;当再次出现线程竞争,锁会升级为轻量级锁,即使用cas方式的加锁;再次又又又出现竞争,才会升级到重量级锁,即monitor那种方式。
以上是关于synchronized实现解析的主要内容,如果未能解决你的问题,请参考以下文章