synchronized的实现原理

Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用管程来支持的。

Java中的每一个对象都可以作为锁,具体表现为以下3种形式。

1)对于普通同步方法,锁是当前实例对象。

2)对于静态同步方法,锁是当前类的Class对象

3)对于同步方法块,锁是Synchronized括号的配置的对象。

1.方法级的同步

方法级的同步是隐式的,即无须通过字节码指令来控制,它实现在方法调用和返回操作之中。虚拟机可以从方法常量池的方法表结构中的ACC_SYNCHRONIZED访问标志得知一个方法是否声明为同步方法。当方法调用时,调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置,如果设置了,执行线程就要求先成功持有管程,然后才能执行方法,最后当方法完成(无论是正常完成还是非正常完成)时释放管程。在方法执行期间,该执行线程持有管程,其他任何线程都不能获取同一个管程。如果一个同步方法执行期间抛出异常,并且在方法内部无法处理此异常,那么这个同步方法所持有的管程将在异常抛出到同步方法之外时自动释放

2.同步代码块

同步一段指令集序列通常是由Java语言中的synchronized语句块来表示的,Java虚拟机的指令集中有monitorenter和monitorexit两条指令来支持synchronized关键字的语义,正确实现synchronized关键字需要Javac编译器与Java虚拟机两者共同协作支持。

monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束和异常处,JVM要保证每个monitorenter必须有对应的monitorexit与之配对。任何对象都有一个monitor与之关联,当且一个monitorenter被持有后,它将处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即尝试获得对象的锁。

编译器必须确保无论方法通过何种方式完成,方法中调用过的每条monitorenter指令都必须执行其对应的monitorexit指令,而无论这个方法是正常结束还是异常结束。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 9,120评论 0 11
  • 概述 互斥访问:synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对...
    jiangmo阅读 3,663评论 0 1
  • 不知不觉走过了一段路程,度过了这一个月的无聊期,其实仔细算算,日子过得很快,再看看眼前的一切,变化不大。普通的人生...
    熏莉阅读 2,669评论 2 1
  • 声明:所有下述言论仅代表个人观点,如有与事实出入或者描述不得当之处和作者以及作者工作单位无关。如需删除本文所记载的...
    _CHARSET阅读 3,247评论 0 0
  • 运用现代的互联网手段方法运作的商业行为都是电商,它包括阿里京东微信拼多多等,电商目前已经非常的普遍,做电商核心是电...
    猪只好爱猪阅读 952评论 0 0