有人可以帮助解释 Java 线程中断这里发生了什么吗?

Can anybody help explain what happens here with Java thread interruption?

这些是我拥有的 3 个 classes:

public class ChildThread extends Thread {
    @Override
    public void run() {
        while (true) {
            System.out.println("Child thread is running.");
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Child thread is interrupted.");
                return;
            }
        }
    }
}

public class MainThread extends Thread{

    public Thread childThread = new ChildThread();

    @Override
    public void run() {
        childThread.start();
    }
}

public class App {

    public static void main(String[] args) {
        MainThread mainThread = new MainThread();
        mainThread.start();
        mainThread.childThread.interrupt();
    }
}

当我运行这个的时候,子线程似乎从来没有被中断过。它不断打印:"Child thread is running." 但是,如果我在 mainThread.childThread.interrupt(); 处放置调试断点,子线程将被中断。

另外,如果我像下面这样更改 App class:

public class App {

    public static void main(String[] args) throws Exception{
        ChildThread childThread = new ChildThread();
        childThread.start();
        Thread.sleep(3000);
        childThread.interrupt();
    }
}

又能用了。子线程在 3 秒后被中断并停止打印。

似乎从直接启动子线程的线程中断和从不直接启动子线程的线程中断行为是不同的。而且根据有无断点也不同。这对我来说太奇怪了。这怎么能在一个复杂的系统中工作?我不认为一个复杂的系统可以保证所有的中断信号都来自线程的原始启动器。

谁能帮忙解释一下?我找不到任何似乎有答案的地方。

您需要 Thread.sleep 才能中断,否则,您甚至在子线程有机会启动之前就已经中断了 运行。根据 API 规范 "Interrupting a thread that is not alive need not have any effect."。因此,实际上,中断语句在线程未处于活动状态时被忽略。没有睡眠,线程在中断后变为活动状态 - 因此永远不会被中断。

public class App {

    public static void main(String[] args) throws InterruptedException {
        MainThread mainThread = new MainThread();
        mainThread.start();
        Thread.sleep(1);    // <== This line is needed as otherwise, the next line will 
                            //      interrupt the thread, even before it has started running!
        mainThread.childThread.interrupt();
    }
}