首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM中的“同步”到底是怎么实现的?

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

作者头像
ImportSource
发布2018-04-03 15:25:28
6760
发布2018-04-03 15:25:28
举报
文章被收录于专栏:ImportSourceImportSourceImportSource

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指令。

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ImportSource 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档