基于本机CPU或字节码的单个指令的Java线程执行

基于本机CPU或字节码的单个指令的Java线程执行,java,multithreading,assembly,jvm,jit,Java,Multithreading,Assembly,Jvm,Jit,首先,我可能无法清楚地描述问题,请留下评论,因为我对我正在询问的案例了解有限 来自OCA/OCP Java®SE 7程序员I&II学习指南 将++语句计算到多个Java字节码指令中,您真的需要 无法控制执行哪些本机指令。准时制 (即时编译器)–大多数Java运行时基于的特性 环境意味着您不知道count++语句何时或是否 将被转换为本机CPU指令,以及它是否结束 作为一条或几条指令 我的问题是,如果一条语句通过JIT转换为本机CPU指令,或者在多线程执行指令时仍然使用java字节码,这有什么不同

首先,我可能无法清楚地描述问题,请留下评论,因为我对我正在询问的案例了解有限

来自OCA/OCP Java®SE 7程序员I&II学习指南

将++语句计算到多个Java字节码指令中,您真的需要 无法控制执行哪些本机指令。准时制 (即时编译器)–大多数Java运行时基于的特性 环境意味着您不知道count++语句何时或是否 将被转换为本机CPU指令,以及它是否结束 作为一条或几条指令

我的问题是,如果一条语句通过JIT转换为本机CPU指令,或者在多线程执行指令时仍然使用java字节码,这有什么不同吗

我的印象是线程在本机CPU指令级别上工作,而不是字节码指令级别,因此即使JIT是否将方法转换为本机CPU指令,低级线程最终也会执行转换字节码的本机CPU指令。 但是如果这是真的,这意味着引用是错误的,因为最后线程将使用本机cpu指令,除了JIT是否将代码转换为本机cpu之外,您能确认吗?

<如果P> > EXED,如果C++语句从<代码>无效实例({ int=0);C++,} /CUT>是字节码上的1条指令,但是在本地CPU上有3条指令,JIT不将方法示例转换为本机CPU指令,并且线程T执行语句C++,<强>将作为字节码指令执行(1条指令)或本机CPU(3条指令)?


任何人都可以为我提供有关我所问主题的资源?

引用是正确的。您无法控制执行哪些本机指令。有很多体系结构和VM类型,您无法确定所有这些


至于您的特殊情况下的字节码,如果您感到好奇,您可以尝试使用
-XX:+UnlockDiagnosticVMOptions-XX:+PrintAssembly
和其他可以使用的选项。

引用是正确的。您无法控制执行哪些本机指令。有很多体系结构和VM类型,您无法确定所有这些


对于特定情况下的字节码,如果您感到好奇,可以尝试使用
-XX:+UnlockDiagnosticVMOptions-XX:+PrintAssembly
和其他可以使用的方法。

所以问题是并发属性会随您的问题而变化。显然,CPU只执行本机指令,所以字节码的JIT或非JIT最终将被转换为本机指令。在机器翻译环境中,即使将
c++
翻译成一条指令(比如x86上的
inc DWORD[rbp]
),也不能保证任何原子性或顺序性,因此机器翻译的可靠性与指令的数量无关。你的英语很难理解。你的问题似乎充满了不正确的假设,这使得理解你真正想要的东西变得更加困难。例如,“JIT将方法转换为字节码”意味着字节码是由JIT生成的,但他们会使用它,因此问题的其余部分甚至没有意义,因为它是建立在错误的假设上的。只需澄清一下:如果
c
是一个局部变量,就像在您的示例中一样,不可能被其他线程看到,因此,它是在一条指令中更新还是在多条指令中更新并不重要。对于记录,它将是一个字节码指令,但在JIT处理后为零本机指令,因为根本不使用结果。如果将
++
运算符应用于堆变量,它将由多个字节码指令组成,这并不重要,但JIT很可能会撕裂操作的读写部分,并将它们与其他更新融合在一起。如果没有正确的线程同步,优化后的代码可以使用以前读取的值,递增它(在CPU寄存器中)并使用它,而根本不将其写入堆内存,以便仅在处理一长串操作后写入净结果。执行线程的结果仍然是相同的(只是执行时间更少),但是如果访问相同的变量而没有适当的同步,其他线程可能会遇到最奇怪的结果。所以问题是并发属性会根据您的问题而改变。显然,CPU只执行本机指令,所以字节码的JIT或非JIT最终将被转换为本机指令。在机器翻译环境中,即使将
c++
翻译成一条指令(比如x86上的
inc DWORD[rbp]
),也不能保证任何原子性或顺序性,因此机器翻译的可靠性与指令的数量无关。你的英语很难理解。你的问题似乎充满了不正确的假设,这使得理解你真正想要的东西变得更加困难。例如,“JIT将方法转换为字节码”意味着字节码是由JIT生成的,但他们会使用它,因此问题的其余部分甚至没有意义,因为它是建立在错误的假设上的。只需澄清一下:如果
c
是一个局部变量,就像在您的示例中一样,不可能被其他线程看到,因此,它是在一条指令中更新还是在多条指令中更新并不重要。对于记录,它将是一个字节码指令,但在JIT处理后为零本机指令,因为根本不使用结果。如果将
++
运算符应用于堆变量,它将由多个字节码指令组成,这并不重要,但JIT完全有可能将操作的读写部分分离,并将它们与其他更新融合在一起