当线程被中断/终止时,finally 块可能不会被执行吗?

Raf*_*ter 5 java multithreading exit

Java 教程中它说try { ... } finally { ... }

注意:如果在执行 try 或 catch 代码时 JVM 退出,则finally 块可能不会执行。同样,如果执行 try 或 catch 代码的线程被中断或终止,则即使应用程序整体继续运行,finally 块也可能不会执行。

线程是否可以被中断杀死我认为这是不可能的?),这样当运行该线程的 JVM没有退出/杀死时,该finally块就不会被执行?(我很困惑,因为上面的引文对此非常明确,没有太大的误解空间。)

编辑:将问题分解为其核心意图。

Mue*_*uel 2

拉斐尔,我相信这是您所追求的边缘情况之一。如果线程在本机上被阻塞(例如从STDIN或 a读取Socket),并且 JVM 处于关闭状态,并且线程被中断,则finally可能不会被调用。

以下示例表明了这一点,但不调用已弃用的方法:

  1. Sleep- 最后调用。
  2. SystemIn- 最后没有被调用。

这个例子非常做作,纯粹是为了演示目的:)

public class Interrupted {

  static final List<Thread> THREADS = Arrays.asList(
      new Thread(new Sleep()),
      new Thread(new SystemIn())
  );
  static final CountDownLatch LATCH = new CountDownLatch(THREADS.size());

  public static void main(String[] args) throws Exception {
    Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
    for (Thread thread : THREADS) {
      thread.start();
    }
    System.out.println("[main] Waiting for threads to start...");
    LATCH.await();
    System.out.println("[main] All started, time to exit");
    System.exit(0);
  }

  static abstract class BlockingTask implements Runnable {
    @Override
    public void run() {
      final String name = getClass().getSimpleName();
      try {
        LATCH.countDown();
        System.out.printf("[%s] is about to block...%n",name);
        blockingTask();
      } catch (Throwable e) {
        System.out.printf("[%s] ", name);
        e.printStackTrace(System.out);
      } finally {
        System.out.printf("[%s] finally%n", name);
      }
    }
    abstract void blockingTask() throws Throwable;
  }

  static class Sleep extends BlockingTask {
    @Override
    void blockingTask() throws Throwable {
      Thread.sleep(60 * 60 * 1000); // 1 hour
    }
  }

  static class SystemIn extends BlockingTask {
    @Override
    void blockingTask() throws Throwable {
      System.in.read();
    }
  }

  static class ShutdownHook implements Runnable {
    @Override
    public void run() {
      System.out.println("[shutdown-hook] About to interrupt blocking tasks...");
      for (Thread thread : THREADS) {
        thread.interrupt();
      }
      System.out.println("[shutdown-hook] Interrupted");
      try {
        for (int i=0; i<10; i++) {
          Thread.sleep(50L);
          System.out.println("[shutdown-hook] Still exiting...");
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

}
Run Code Online (Sandbox Code Playgroud)