如果它实际计算就不可能中断线程?

Impossible to interrupt thread if its actually computing?

鉴于此代码...

public class SimpleTest {

  @Test
  public void testCompletableFuture() throws Exception {
    Thread thread = new Thread(SimpleTest::longOperation);
    thread.start();

    bearSleep(1);

    thread.interrupt();

    bearSleep(5);
  }

  public static void longOperation(){
    System.out.println("started");
    try {

      boolean b = true;
      while (true) {
        b = !b;
      }

    }catch (Exception e){
      System.out.println("exception happened hurray!");
    }
    System.out.println("completed");
  }

  private static void bearSleep(long seconds){
    try {
      TimeUnit.SECONDS.sleep(seconds);
    } catch (InterruptedException e) {}
  }
}

想象一下,您有一些不会抛出中断执行的东西而不是这个 while(true)(例如,一个实际计算某些东西的递归函数)。

这东西怎么杀?为什么它不死?

请注意,如果我不在那里输入 Exception 并使用 InterruptedException,它甚至不会编译,说 "interrupted exception will never be thrown",我不明白为什么。也许我想手动打断它...

Thread#interrupt 或多或少是用一个标志实现的。如果线程在某些操作上被阻塞,例如:IO 或同步原语(请参阅 Javadoc),线程将被解除阻塞并在该线程中抛出 InterruptedException。否则,设置一个简单的状态标志,指示线程被中断。

您的代码需要使用 Thread#interrupted() or Thread#isInterrupted()(或处理 InterruptedException)检查该状态。

请注意,使用 static 方法检查状态会清除状态。

我假设您指的是这段代码:

try {
    boolean b = true;
    while (true) {
        b = !b;
    }
} catch(Exception e) {
    System.out.println("exception happened hurray!");
}

你不能在这里捕获 InterruptedException 的原因是因为该块内部没有任何东西可以抛出 InterruptedExceptioninterrupt() 本身不会使线程跳出循环,相反,它本质上是向线程发送一个信号,告诉它停止正在执行的操作并执行其他操作。如果你想 interrupt() 打破循环,试试这个:

boolean b = true;
while (true) {
    b = !b;
    // Check if we got interrupted.
    if(Thread.interrupted()) {
        break; // Break out of the loop.
    }
}

现在线程将检查它是否被中断,一旦被中断就跳出循环。不需要 try-catch