我究竟如何中断一个线程?

How exactly do I interrupt a thread?

我正在尝试弄清楚如何中断一个线程。我知道之前有人问过这个问题,但我不确定我是否理解正确。

我目前有:

public class Test implements Runnable {
    public void run() {
        int i = 0;
        while(!Thread.currentThread().isInterrupted() && i < 100) {
            System.out.println(i++);
        }
    }
    public static void main(String args[]) {
        Thread x = new Thread(new Test());
        x.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(i+100);
            if (i == 75) {
                x.interrupt();
            }
        }
    }
}

这两个线程都计数为 100。这是一个简单的例子,我知道,但我突然想到,如果我在 run 方法中做一些更复杂的事情,那么外部的 while 循环可能不会足够好。所以我要问的是:

如果我在 run 方法中有例如 50 行代码,并且我想在这 50 行代码中的任何地方中断线程,那么我将不得不加载 ifs 检查它在每一行之间没有被打断?就我目前对整个事情的理解而言,情况就是这样......这让我觉得我错过了一些东西。

感谢您的帮助:)

您的理解是正确的 - interrupt 用于合作而不是先发制人的中断。由目标线程决定何时可以安全地被中断,并在那个时候进行适当的检查。如果线程在阻塞时被中断,某些阻塞操作将抛出 InterruptedException,但除此之外,您可以根据需要检查 Thread.interrupted()。在大多数算法中,您 不希望 允许在任意点中断,但仅在您知道状态将保持一致的明确定义的地方。

请注意,您应该使用 Thread.interrupted() 而不是 Thread.currentThread().isInterrupted() 进行检查,因为前者会在检查后重置中断标志。一旦 isInterrupted return 为真,它将在每次调用时继续为 return 真,直到标志被重置,这可能不是您想要的。

Ian Roberts 已经说过的话,

如果您不是在编写顶级应用程序(即,如果您正在编写的代码将被其他任何人调用),那么只有一种合理的方法来处理 InterruptedException ;

  • 安全地中止呼叫者要求您执行的任何操作,
  • 确保让事情处于调用者可以开始新操作的状态(如果调用者想要这样做的话),并且
  • 重新投掷InterruptedException.

以任何其他方式运行的代码可能会让调用它的人感到惊讶,而让调用者感到惊讶从来都不是一个好主意。

如果您正在编写顶级应用程序,那么请继续InterruptedException 以适合您的任何方式进行处理。 (只希望您调用的库不会做任何让您感到惊讶的事情。)