线程似乎没有干净地退出 - 线程挂起

Thread doesn't seem to exit cleanly - thread hang

所以我尝试根据我对 Java 内存模型 (JMM) 的了解进行一些测试,因为我想看看它们如何应用于 try-catch 块中的初始化+赋值抛出一个异常,我得到了我想要的结果(不相关,但我想知道在 try-catch 中分配是否可以在初始化之前发生,然后在抛出一些异常之前,其他线程是否可以看到抛出异常之前未初始化的对象 - 答案似乎是否定的),但是我遇到了一些与我的线程相关的奇怪问题 运行.

基本上,我的线程似乎永远不会退出。我 运行 我的代码在调试器中完成,我可以看到两个线程 运行。我的主线程是 Thread,而线程是我创建的 Thread-1。在我完成 main 方法后,我的主线程消失了,如预期的那样被 DestroyJavaVM 取代。但是,Thread-1 似乎在等待什么。

真正让我困惑的部分,除了代码太简单以至于搞砸之外,是如果我把一个

System.out.print("");

在 while 块内部,然后由 I/O 引起的减速似乎导致线程在它正在做的任何事情上都 "catch-up",并看到中断。我注意到的另一件事是,如果我在 "finished" #println() 语句上放置一个断点,线程将在该行中断,并允许我继续,这会导致标准输出中的打印语句,程序退出。这对我来说没有多大意义。幕后发生了什么导致创建的线程看不到中断?

这是我的测试代码,删除了与我测试 JMM 相关的不重要位:

public class Foo{
    static Foo p;

    public static void main(String [] args){
        Thread t = new Thread(new Runnable(){
            @Override
            public void run() {
                while(!Thread.currentThread().isInterrupted()){
                }
                System.out.println("finished");
            }

        });
        t.start();
        for(int i = 0; i < 100000; i++){
            try{
                p = new Foo();
            }catch(Exception pse){
            }
        }
        t.interrupt();
        System.out.println("main-method-completed");
    }
}

只要线程运行其 while 循环,它就不会从系统中的其他线程获取任何消息。例如,如果您这样做,Thread.sleep(1); 线程将暂停,并且会发生上下文切换到其他内容。当线程恢复时,它会得到一些主循环线程的中断通知。

如果你想停止线程中的循环,你可以使用一个 volatile 变量(这些变量是从共享内存中明确写入和读取的,并且非常昂贵),或者使用,例如,一个 java.util.conncurrent.atomic.AtomicBoolean,至少在理论上可以使用一些更便宜的方法在线程之间传递其状态。

您可能已经重现了错误 JDK-6772683 : Thread.isInterrupted() fails to return true on multiprocessor PC