在为类似Java的语言编写自己的编译器时,我在编译synchronized blocks
时遇到了麻烦。我想出了以下想法来将它们简化为try-finally
块:
synchonized (obj) {
statements...
}
可替换为
Object _lock = obj
_monitorEnter(lock)
try {
statements...
}
finally {
_monitorExit(lock)
}
编辑
我的实现以前对主体中的return
和throw
语句进行了一些特殊处理。基本上,它将在每个*return
或throw
指令之前手动加载所有lock
变量和monitorexit
变量。这是由finally
块处理的,还是我仍然需要这些检查?
你的假设是正确的。Java语言中的synchronized
块是通过monitorenter
和monitorexit
指令实现的。您可以在这里查看JVM规范的详细信息。
Java虚拟机中的同步是通过监视器进入和退出来实现的,可以是显式的(通过使用monitorenter和monitorexit指令),也可以是隐式的(通过方法调用和返回指令)。
编译器生成的字节码将处理在synchronized
正文中抛出的所有异常,因此您的try-finally方法在这里可以很好地工作。
finally
语句的规范没有说明任何有关释放监视器的内容。第一个链接中提供的示例显示了包装在synchronized
块中的简单方法的字节码。如您所见,处理任何可能的异常以确保monitorexit指令执行。您应该在编译器中实现相同的行为(编写将在finally语句中释放monitor的代码)。
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
运行显然会导致,但运行不会(程序似乎只是无限期运行)。这是为什么?
本文向大家介绍说明PowerShell中的Try / Catch / Finally块,包括了说明PowerShell中的Try / Catch / Finally块的使用技巧和注意事项,需要的朋友参考一下 PowerShell中的Try / Catch块用于处理脚本中产生的错误。具体而言,错误应该是终止错误。在最后在PowerShell中块不是强制性的,每次沿写try / catch语句,但它会
问题内容: 根据Java语言规范的第§14.20.2节 通过首先执行try块来执行带有finally块的try语句。然后有一个选择: 如果try块的执行正常完成,则执行finally块,然后可以选择: 如果finally块正常完成,则try语句正常完成。 如果finally块由于原因S突然完成,则try语句由于原因S突然完成 如果我正确地解释了它,那么在执行try块之后最终会被调用,但是所有这些如
主要内容:1 什么是Java同步代码块,2 Java同步代码块的要点,3 Java同步代码块的语法,4 Java同步代码块的例子1,5 Java同步代码块的例子21 什么是Java同步代码块 同步代码块可用于对方法的任何特定资源执行同步。 假设您的方法中有50行代码,但是您只想同步5行,则可以使用synchronized代码块。 如果将方法的所有代码放在同步代码块中,它的效果与同步方法相同。 2 Java同步代码块的要点 同步代码块用于锁定任何共享资源的对象。 同步代码块的范围小于该方法。 3
假设以下两种计数器实现: 乍一看,原子应该更快、更具可扩展性。我相信他们是的。但是它们始终比同步块快吗?或者当该规则被打破时,存在某些情况(例如SMP/单CPU机器、不同的CPU ISA、操作系统等)?