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

时间:2015-05-18 21:14:49

标签: java multithreading interrupt

所以我试图根据我对Java内存模型(JMM)的一些知识进行一些测试,因为我想看看它们如何应用于try-catch块中的初始化+赋值,并抛出异常,并且我获得了我想要的结果(没有相关,但我想知道如果在try-catch中,如果分配可能在初始化之前发生,并且反过来在抛出一些异常之前,其他一些Thread可能会在异常之前看到未初始化的Object被抛出 - 答案似乎是否定的,但是我遇到了与我的线程运行有关的奇怪事情。

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

真正让我感到困惑的部分,除了代码太简单,搞砸了,如果我放了一个

System.out.print("");

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

这是我测试的代码,删除了与我测试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");
    }
}

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

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

如果你想在线程中停止循环,你可以使用volatile变量(这些变量是从共享内存写入和读取的,并且非常昂贵),或者使用例如{{1}至少在理论上可以使用一些较便宜的方法来传递线程之间的状态。