Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用sleep将重新加载java?; 在java spec 17.3中,睡眠和产量_Java_Multithreading_Jvm - Fatal编程技术网

调用sleep将重新加载java?; 在java spec 17.3中,睡眠和产量

调用sleep将重新加载java?; 在java spec 17.3中,睡眠和产量,java,multithreading,jvm,Java,Multithreading,Jvm,17.3睡眠和产量 sleep使当前执行的线程在指定的持续时间内休眠(暂时停止执行),具体取决于系统计时器和调度程序的精度和准确性。线程不会失去任何监视器的所有权,执行的恢复将取决于执行线程的调度和处理器的可用性 需要注意的是,Thread.sleep和Thread.yield都没有 同步语义。特别是,编译器不必刷新 在调用Thread.sleep之前,将缓存在寄存器中的内容写入共享内存 或者Thread.yield,编译器也不必在调用Thread.sleep或Thread.yield后重新加载

17.3睡眠和产量

sleep使当前执行的线程在指定的持续时间内休眠(暂时停止执行),具体取决于系统计时器和调度程序的精度和准确性。线程不会失去任何监视器的所有权,执行的恢复将取决于执行线程的调度和处理器的可用性

需要注意的是,Thread.sleep和Thread.yield都没有 同步语义。特别是,编译器不必刷新 在调用Thread.sleep之前,将缓存在寄存器中的内容写入共享内存 或者Thread.yield,编译器也不必在调用Thread.sleep或Thread.yield后重新加载缓存在寄存器中的值

例如,在以下(断开的)代码片段中,假设this.done是一个非易失性布尔字段:

编译器可以自由地读取this.done字段一次,并在每次执行循环时重用缓存的值。这意味着循环永远不会终止,即使另一个线程更改了This.done的值

它描述线程从不重新加载缓存在寄存器中的变量,但当我运行以下代码时,它不工作,循环终止 结果是: java spec 17.3中的代码有什么不同? 为什么在呼叫睡眠后会重新加载字段?
规范没有规定编译器(或运行时)必须确保该字段从未重新加载或与其他线程同步

“不必”、“可以自由”、“没有任何语义”

它只说这样的行为是允许的(因为它在性能优化中是有意义的)

因此,当涉及多个线程时,您必须明确它应该如何工作:要么使其易失性,要么使其线程本地。

请再次阅读:

“编译器可以自由读取此字段。只需执行一次”


是免费的,意味着它只能阅读一次,或者每次都可以自行阅读。在您的情况下,它每次都读取,这是规范允许的合法行为。

因此它取决于编译器?这是未指定的行为。弄清楚它在特定条件下是如何工作的几乎没有意义。坚持指定的内容并相应地编写代码。
while (!this.done)
    Thread.sleep(1000);
public class TestDemo {

    private  static boolean  keepRunning = true;

    public static void main(String[] args)  throws Exception {
        new Thread(
            ()->{
                while (keepRunning){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {

                    }
                }
                System.out.println("loop terminates");
            }
        ).start();
        Thread.sleep(1000);
        keepRunning = false;
        System.out.println("keepRunning is false now");
    }
}
    C:\Users\LuoYY\Desktop>javac TestDemo.java

    C:\Users\LuoYY\Desktop>java TestDemo
    keepRunning is false now
    loop terminates