Java 为什么有JVM指令“monitorenter/monitorexit”,但没有“wait/notifyAll”(它们是本机调用)?

Java 为什么有JVM指令“monitorenter/monitorexit”,但没有“wait/notifyAll”(它们是本机调用)?,java,bytecode,language-design,Java,Bytecode,Language Design,当我们编写synchronizedsome_object{}时,我们可以看到作为字节码发出的两条JVM指令monitorenter/monitorexit 当我们编写synchronizedsome_object{some_object.wait}时,我希望看到一些特殊的JVM指令,比如wait,但是没有——相反,wait/notify是作为本机C函数实现的 为什么会有这样的不一致性?要么将它们全部作为JNI,要么作为java字节码?是有特定的历史原因,还是只是品味问题 上下文:我对此感兴趣,因

当我们编写synchronizedsome_object{}时,我们可以看到作为字节码发出的两条JVM指令monitorenter/monitorexit

当我们编写synchronizedsome_object{some_object.wait}时,我希望看到一些特殊的JVM指令,比如wait,但是没有——相反,wait/notify是作为本机C函数实现的

为什么会有这样的不一致性?要么将它们全部作为JNI,要么作为java字节码?是有特定的历史原因,还是只是品味问题

上下文:我对此感兴趣,因为在字节码中包含所有monitorenter/monitorexit/wait/notify将允许“不处理JNI的Java字节码程序正确性验证器”来验证不使用JNI的并发Java程序。目前,此类假设工具必须解决等待/通知问题

我希望看到特殊的JVM指令,比如wait

我不会的。在我看来,这是不一致的——在源代码中,您只是在调用一个方法,所以您也在字节码中调用一个方法是有道理的。否则,编译器必须具备这些方法的专门知识,而目前还没有

可以说,通过方法调用实现monitorenter和monitorexit会更有意义,例如,它们在.NET中也是如此。某些方法总是本机的,并且与JVM本身有着紧密的联系——我不认为这有什么不合理的地方,我也不希望通过单独的字节码操作来实现这些方法。然而,考虑到synchronized是一种类似try/catch/finally的语言构造,而不仅仅是一个常规的方法调用,因此我对synchronized使用特殊字节码支持它没有太多问题

我希望看到特殊的JVM指令,比如wait

我不会的。在我看来,这是不一致的——在源代码中,您只是在调用一个方法,所以您也在字节码中调用一个方法是有道理的。否则,编译器必须具备这些方法的专门知识,而目前还没有


可以说,通过方法调用实现monitorenter和monitorexit会更有意义,例如,它们在.NET中也是如此。某些方法总是本机的,并且与JVM本身有着紧密的联系——我不认为这有什么不合理的地方,我也不希望通过单独的字节码操作来实现这些方法。然而,考虑到synchronized是一种类似try/catch/finally的语言构造,而不仅仅是一个常规的方法调用,因此我对synchronized使用特殊字节码支持它没有太多问题。

没有必要使用验证程序来处理JNI,因为wait和notify调用的语义已经很好地指定。这与专用字节码指令没有什么不同。这同样适用于热点优化器如何处理许多众所周知的方法调用,其中可能包括等待和通知。它不一定生成代价高昂的JNI调用,而是直接生成执行这些低级操作的代码。以这种方式处理的方法称为see或

有太多了,如果你试图为它们中的每一个保留一个操作码,你就不能再称之为字节码了。此外,以这种方式处理哪些方法取决于实际的JVM实现及其运行的硬件体系结构。它也可能在不同版本之间发生变化,因此没有必要通过定义字节码指令将其刻在石头上

您写道“目前,此类假设工具必须解决等待/通知问题”。事实上,处理这些特殊方法并不是一种变通方法。这就是这样一个审计工具与许多方法(如中声明的方法)的关系,这些方法具有类似的线程相关语义,但现在还有许多其他众所周知的并发工具需要处理


创建monitorenter和monitorexit指令但在对象上创建wait和notify方法的确切决定是历史性的,可以追溯到20多年前。今天,如果开发者不得不再次做出决定,那么这个决定看起来可能会有所不同。但我想它更倾向于使monitorenter和monitorexit成为在后台调用的特殊方法,而不是字节码指令。首先,它们不再是唯一的线程同步工具。其次,它是如何在最近的JVM中添加大多数新特性的,最好是作为方法,即使大多数(如果不是全部的话)实现都会对其进行内部化。

没有必要使用验证程序来处理JNI,因为wait和notify调用的语义已经很好地指定。这与专用字节码指令没有什么不同。这同样适用于热点优化器如何处理许多众所周知的方法调用,其中可能包括等待和通知。事实并非如此 必须生成代价高昂的JNI调用,而不是直接生成执行这些低级操作的代码。以这种方式处理的方法称为see或

有太多了,如果你试图为它们中的每一个保留一个操作码,你就不能再称之为字节码了。此外,以这种方式处理哪些方法取决于实际的JVM实现及其运行的硬件体系结构。它也可能在不同版本之间发生变化,因此没有必要通过定义字节码指令将其刻在石头上

您写道“目前,此类假设工具必须解决等待/通知问题”。事实上,处理这些特殊方法并不是一种变通方法。这就是这样一个审计工具与许多方法(如中声明的方法)的关系,这些方法具有类似的线程相关语义,但现在还有许多其他众所周知的并发工具需要处理


创建monitorenter和monitorexit指令但在对象上创建wait和notify方法的确切决定是历史性的,可以追溯到20多年前。今天,如果开发者不得不再次做出决定,那么这个决定看起来可能会有所不同。但我想它更倾向于使monitorenter和monitorexit成为在后台调用的特殊方法,而不是字节码指令。首先,它们不再是唯一的线程同步工具。其次,它是如何在最近的JVM中添加大多数新特性的,最好是作为方法,即使大多数(如果不是全部的话)实现都会对其进行内部化。

为什么不呢?纯粹基于观点,除非你能让吉姆·戈斯林接上电话。我不知道吉姆的情况,但詹姆斯·戈斯林可能会同意乔恩·斯基特的观点。一个定义为方法并使用方法字节码,另一个定义为具有自己特殊字节码的语言构造。两者可能都是在本机代码中实现的。但这取决于JVM,为什么不呢?纯粹基于观点,除非你能让吉姆·戈斯林接上电话。我不知道吉姆的情况,但詹姆斯·戈斯林可能会同意乔恩·斯基特的观点。一个定义为方法并使用方法字节码,另一个定义为具有自己特殊字节码的语言构造。两者可能都是在本机代码中实现的。但这取决于JVM。这回答了问题!事实上,该工具不需要调用这样的JNI函数,而可以简单地假设这些方法的“正确”语义看起来像是明确定义了内部函数的语义。旁白:你说它们不再是唯一的线程同步工具是什么意思?monitorenter用于线程同步之外的其他用途?哪一个?不,这意味着还有其他线程同步工具。最值得注意的是,您可以对和条件执行相同的操作,而字节码将只包含方法调用。所以synchronized在源代码级别上有不同的语法,但实现了相同的目的。所以它是否应该有自己的字节码指令还有争议……这回答了这个问题!事实上,该工具不需要调用这样的JNI函数,而可以简单地假设这些方法的“正确”语义看起来像是明确定义了内部函数的语义。旁白:你说它们不再是唯一的线程同步工具是什么意思?monitorenter用于线程同步之外的其他用途?哪一个?不,这意味着还有其他线程同步工具。最值得注意的是,您可以对和条件执行相同的操作,而字节码将只包含方法调用。所以synchronized在源代码级别上有不同的语法,但实现了相同的目的。所以它是否应该有自己的字节码指令还有争议…