线程无法正常停止

时间:2019-03-29 09:35:22

标签: java

我是Java并发编码的新手,遇到问题。以下代码在运行时无法停止。谁能告诉我为什么?谢谢

import java.util.concurrent.TimeUnit;
public class Test {
    private static boolean stop;

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            System.out.println(Thread.currentThread());
            System.out.println(stop);
            while (!stop) {
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);
        stop = true;
        System.out.println(Thread.currentThread());
        System.out.println(stop);
    }
}

我还尝试运行以下代码,它可能会停止。谁能告诉我为什么?谢谢

import java.util.concurrent.TimeUnit;

public class Test {
    private static boolean stop;

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            System.out.println(Thread.currentThread());
            System.out.println(stop);
            while (!stop) {
                System.out.println("  ");
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);
        stop = true;
        System.out.println(Thread.currentThread());
        System.out.println(stop);
    }
}

2 个答案:

答案 0 :(得分:8)

因为您没有向编译器指示stop可能会被多个线程更改并读取:

private static boolean stop;

可以对此进行优化:

while (!stop) {
}

if (!stop) {
  while (true) {
  }
}

如果stop最初为假,它将永远不会停止。

声明stop volatile

private static volatile boolean stop;

不允许这种优化。

答案 1 :(得分:-3)

JVM通常在实际执行代码之前先对其进行优化。对于您而言,while(!stop){}已优化为while(true){}。发生这种情况是因为您没有通过同步函数显式访问静态变量,并且JVM假定该变量不会以线程不安全的方式进行更改。

为避免优化,请将任何内容放入while循环中。您可以执行以下操作:

while(!stop) {
    try{
        Thread.sleep(1); // You could also call any other function here.
    }
    catch(Exception e) { }
}

在这种情况下,JVM不会尝试优化,并且您的代码将按预期执行。

编辑: 尽管目前可以使用,但基于评论,我同意在将来的版本(或JDK / JVM的其他并行实现)中可以更改。将变量声明为volatile是避免该优化的最佳方法。