当一个线程被中断/杀死时,最终块可能无法执行吗?

在Java教程中,它说到try { ... } finally { ... }

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

是否可以中断杀死一个线程( 我认为这是不可能的? ),以便在运行此线程的JVM 退出/ finally时不会执行finally块? (我很困惑,因为上面引用的内容非常明确,误解的空间不大。)

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

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

以下示例在不调用弃用方法的情况下指示此情况:

  1. Sleep – 最后调用。
  2. SystemIn – 最终未被调用。

这个例子非常人为,纯粹是出于演示目的:)

 public class Interrupted { static final List 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(); } } } } 

好吧,我的立场得到纠正。 可以使用弃用的方法:

 @Test public void testThread() throws Exception { Thread thread = new Thread(new MyRunnable()); thread.start(); Thread.sleep(100); thread.suspend(); Thread.sleep(2000); } class MyRunnable implements Runnable { @Override public void run() { System.out.println("Start"); try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("Done"); } } } 

由于在线程处于睡眠状态时(很可能)会发生暂停,因此将永远不会执行finally块。