Java 在其他指令/语句之前出现的指令/语句是否保证首先执行?

Java 在其他指令/语句之前出现的指令/语句是否保证首先执行?,java,Java,考虑Joshua Bloch的《Java并发实践》一书中的片段- public class NoVisibility{ private static boolean ready; private static int number; private static class ReaderThread extends Thread{ public void run(){ while(!ready) T

考虑Joshua Bloch的《Java并发实践》一书中的片段-

public class NoVisibility{
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread{
        public void run(){
            while(!ready)
                Thread.yield();
            System.out.println(number);
        }
    }

    public static void main(String[] args){
        new ReaderThread().start();
        number = 42;                            // Statement 1
        ready = true;                           // Statement 2
    }
}
对于JVM启动的main线程,是否保证将在语句2之前执行语句1

我完全理解ReaderThread可能无法看到上述两个静态变量的更新值。我不是在寻求解决办法。但是如果语句1在语句2之前执行,ReaderThread是否仍然可以看到ready的更新值,而不是number的更新值?这就是重新排序的一般含义吗


同一本书页面底部的一段话揭示了这一点-

不能保证在一个线程中执行操作 按照程序给出的顺序,只要不重新排序 即使重新排序很明显,也可以从该线程中检测到 到其他线程

这里有点混乱-

作者说。。。只要重新排序无法从该线程中检测到。。。同时,他说-

-即使重新排序对其他线程是明显的(清晰可见)


如果在这种情况下,重新排序对其他线程是清晰可见的,那么他为什么同时说“只要重新排序在该线程内不可检测到”如果重新排序可见,则意味着它也可检测到。不是吗?

一般来说,这是不能保证的。此外,不保证发生更新,因为其中一个字段中没有添加任何
volatile
。这将同步线程的缓存,并保证顺序

(我希望我是对的。)


澄清(我希望)

给定的场景并不太关注jvm处理的java字节码。通常情况下,编译器不会巧妙地按顺序重新排列或解释字节码。它是运行在具有本地线程缓存的线程中的实时编译代码,重复地保存公共变量

volatile标记的字段确保这些公共变量与所有线程同步。当然,只要结果正常,单个线程可以按任意顺序执行代码

y = ++x;
以下伪程序集的实际执行

1. move from @x to register1
2. increment register1
3. move from register1 to @x
4. move from register1 to @y
5. synchronize @x and @y
在不同的处理器上可能会有很大的不同。一个或两个变量可能缓存在线程内存中,或者需要写入far变量,或者不需要

当然,可以保证处理相同的线程时会给出正确的结果。没有人看到,顺序是不相关的:4可能比3早,或者由于记忆的原因比3快

如果3。四,。如果JIT编译被切换,同一线程将不会看到/检测到任何差异,但其他线程可能首先看到y中的更改。这是没有volatile的

这一切都是相当深奥的,太低级了。有人可能会想,它出现在语言规范中,就像
byte
变量在内部存储在一个4字节的字中一样。它处理与实现相关的问题,比如缺少字节操作。当有人对这个主题感兴趣时,可以使用汇编程序,也许可以与C结合使用,并尝试一下这些东西。否则,请远离不安全的编程


“是”这些陈述是按照您的书面顺序执行的,对于您的第二个问题:您可以找到一个很好的例子。所以是的,这是可能的。“在线程中不可检测”意味着在当前代码中它是不可检测的。e、 g.类似于
foo=1;睡十分钟;foo=2
可能只是从一开始就设置foo=2,因为它在执行线程中是不可检测的(它不检查值),但是其他线程在十分钟结束之前会看到foo==2。。。。执行顺序有保证。确实-但仅在当前线程中,另一个线程可能“看到”不同的东西:。请不要写你不确定的答案about@specializtJIT编译器和CPU可以自由地对这些语句重新排序。没有什么可以阻止,你也不希望它。。。。只有在重新排序“产生与合法执行一致的结果”的情况下,才可以在同一个线程中进行重新排序,因此实际上这并不重要,重新排序本身就是一个实现细节,保证结果一致。@是的,对于不同的线程,当然,对于单个线程,重新排序是不相关的(谁会发现呢?)。正如你所评论的。我对你所引述的技术细节表示怀疑。我喜欢你的纠正意见,谢谢。也请回答问题。@JoopEggen:谢谢。如果你也能回答第二部分,那将非常有帮助。