JVM中的“同步”到底是怎么实现的?

JVM中的Synchronization是使用monitor entry和exit来实现的。不管是显式的还是隐式的。显式的是通过使用monitorentermonitorexit这个两个指令来实现的。隐式的是通过method的调用以及return的指令来实现的。

在Java编程语言中,同步用到最多的地方恐怕就是synchronized方法了。synchronized方法不是用上面说到的monitorentermonitorexit来实现的

而是简单的通过读取在run-time constant pool中的ACC_SYNCHRONIZED flag来识别的。这个ACC_SYNCHRONIZEDflag通过方法调用指令来检查的。其实就是设置了个标识位。

monitorentermonitorexit这两个指令被用作synchronized statements的编译工作上。也就是我们常说的“同步块”。像下面这样:

void onlyMe(Foo f) {

synchronized(f) {

doSomething();

}

}

上面这段代码被编译成下面这个样子:

Method void onlyMe(Foo)

0 aload_1 // Push f

1 dup // Duplicate it on the stack

2 astore_2 // Store duplicate in local variable 2

3 monitorenter // Enter the monitor associated with f

4 aload_0 // Holding the monitor, pass this and...

5 invokevirtual #5 // ...call Example.doSomething()V

8 aload_2 // Push local variable 2 (f)

9 monitorexit // Exit the monitor associated with f

10 goto 18 // Complete the method normally

13 astore_3 // In case of any throw, end up here

14 aload_2 // Push local variable 2 (f)

15 monitorexit // Be sure to exit the monitor! 16 aload_3 // Push thrown value... 17 athrow // ...and rethrow value to the invoker

18 return // Return in the normal case

Exception table:

From To Target Type

4 10 13 any

13 16 13 any

编译器会保证不管方法调用是怎么完成的,都要保证monitorexit指令最终被执行,只要monitorenter指令被执行了,那么monitorexit必须也要被执行。也就是他们两个必须成对出现做事情。不管是方法调用正常完成还是抛出异常而结束。为了能够强制这对指令在任何情况下都成对出现,编译器生成一些exception handlers,这些handler声称将会匹配可能出现的任何异常,并且每个handler相关的代码会保证执行monitorexit指令。

这极有可能是东半球最具良心的公众号,也是正义的公众号!

原文发布于微信公众号 - ImportSource(importsource)

原文发表时间:2016-08-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java、Spring、技术分享

JVM学习笔记

  java引用类型分为四种:类、接口、数组类和泛型参数。其中泛型参数会在编译过程中被擦除。因此 Java 虚拟机实际上只有前三种。在类、接口和数组类中,数组类...

1142
来自专栏机器学习从入门到成神

2015百度校招笔试真题以及解析(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

1982
来自专栏北京马哥教育

搞定Linux Shell文本处理工具,看完这篇集锦就够了

Linux Shell是一种基本功,由于怪异的语法加之较差的可读性,通常被Python等脚本代替。既然是基本功,那就需要掌握,毕竟学习Shell脚本的过程中,还...

3232
来自专栏从流域到海域

《笨办法学Python》 第20课手记

《笨办法学Python》 第20课手记 本节课讲函数与文件,内容比较简单,但请注意常见问题解答,你应该记住那些内容。 指针表示存储地址。 原代码如下: from...

1996
来自专栏chenssy

【死磕Java并发】-----Java内存模型之重排序

在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件: 1. 在单线程环境...

1462
来自专栏IT可乐

Spring详解(三)------DI依赖注入

  上一篇博客我们主要讲解了IOC控制反转,也就是说IOC 让程序员不在关注怎么去创建对象,而是关注与对象创建之后的操作,把对象的创建、初始化、销毁等工作交给s...

2005
来自专栏程序员互动联盟

【记忆卡片】Linux sed命令

sed 在脚本使用时作用非常大,能完成很多更改功能,谁用谁知道 功能说明:利用script来处理文本文件。 语 法:sed [-hnV][-e<script>...

37813
来自专栏Java学习网

Java内存模型深度解读

Java内存模型深度解读 Java内存模型规范了Java虚拟机与计算机内存是如何协同工作的。Java虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一...

2577
来自专栏你不就像风一样

深入理解Java虚拟机(类文件结构+类加载机制+字节码执行引擎)

周志明的《深入理解Java虚拟机》很好很强大,阅读起来颇有点费劲,尤其是当你跟随作者的思路一直探究下去,开始会让你弄不清方向,难免有些你说的啥子的感觉。但知识不...

1292
来自专栏前端侠2.0

co yield避免嵌套详细代码示例。

1471

扫码关注云+社区

领取腾讯云代金券