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

Java 当线程被中断/终止时,finally块可能不会执行吗?,java,multithreading,exit,Java,Multithreading,Exit,其中说的是关于尝试{…}最后{…}: 注意:如果JVM在执行try或catch代码时退出, 那么finally块可能不会执行。同样,如果线程 执行try或catch代码被中断或终止,最后 块可能不会执行,即使应用程序作为一个整体 继续 线程可以被或杀死()这样,当运行该线程的JVM未退出/杀死时,finally块将不会被执行,这是真的吗?(我感到困惑,因为上面的引文对此相当明确,没有多少误解的余地。) 编辑:把问题分解成它的核心意图。好吧,我的观点是正确的。可以使用不推荐使用的方法: @Test

其中说的是关于
尝试{…}最后{…}

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

线程可以被杀死()这样,当运行该线程的JVM未退出/杀死时,
finally
块将不会被执行,这是真的吗?(我感到困惑,因为上面的引文对此相当明确,没有多少误解的余地。)


编辑:把问题分解成它的核心意图。

好吧,我的观点是正确的。可以使用不推荐使用的方法:

@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
块将永远不会执行。

Rafael,我相信这是您所追求的边缘案例之一。如果线程在本机上被阻塞(例如从
STDIN
Socket
读取),并且JVM处于关闭状态,并且线程被中断,那么
最终可能不会被调用

以下示例在不调用已弃用方法的情况下说明了这一点:

@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");
        }
    }
}
  • Sleep
    -最后调用
  • SystemIn
    -最后不调用
  • 该示例非常做作,仅用于演示目的:)

    公共类中断{
    静态最终列表线程=Arrays.asList(
    新线程(新睡眠()),
    新线程(新SystemIn())
    );
    静态最终倒计时闩锁=新倒计时闩锁(THREADS.size());
    公共静态void main(字符串[]args)引发异常{
    Runtime.getRuntime().addShutdownHook(新线程(新ShutdownHook()));
    用于(线程:线程){
    thread.start();
    }
    System.out.println(“[main]正在等待线程启动…”);
    satch.wait();
    System.out.println(“[main]全部启动,退出时间”);
    系统出口(0);
    }
    静态抽象类BlockingTask实现可运行{
    @凌驾
    公开募捐{
    最终字符串名称=getClass().getSimpleName();
    试一试{
    倒计时();
    System.out.printf(“[%s]即将阻止…%n”,名称);
    阻塞任务();
    }捕获(可丢弃的e){
    System.out.printf(“[%s]”,名称);
    e、 printStackTrace(系统输出);
    }最后{
    System.out.printf(“[%s]最后是%n”,名称);
    }
    }
    抽象void blockingTask()抛出可丢弃的;
    }
    静态类睡眠扩展了BlockingTask{
    @凌驾
    void blockingTask()抛出可丢弃的{
    线程。睡眠(60*60*1000);//1小时
    }
    }
    静态类SystemIn扩展BlockingTask{
    @凌驾
    void blockingTask()抛出可丢弃的{
    System.in.read();
    }
    }
    静态类ShutdownHook实现Runnable{
    @凌驾
    公开募捐{
    System.out.println(“[shutdown hook]即将中断阻塞任务…”);
    用于(线程:线程){
    thread.interrupt();
    }
    System.out.println(“[shutdown hook]中断”);
    试一试{
    
    对于(int i=0;在应用程序servlet中可能会写入数百个
    try-catch-finally
    块。您的问题的确切含义是什么?我想知道,当JVM未关闭时,已经输入了相应的
    try
    块时,
    finally
    中的代码怎么可能没有执行引用他的话,我知道即使不调用
    Thread.kill
    ,线程也可以这样做。我想知道servlet容器是否有办法关闭web应用程序,以至于我无法依赖
    最终执行
    。可能重复的,如教程和可能的dup Q/a中所述,这是
    最终的唯一方法y
    未执行是指JVM停止。这是指,通过执行
    System.exit(0);
    或JVM崩溃。@Luigimendoza是的。但问题是,yeah最终可以被中断(如果你做了愚蠢和疯狂的事情).OP请看我的答案。也许这会有帮助。这不只是操作系统在起作用吗?我不这么认为。上面的代码会立即触发中断,操作系统不会在那个时间点等待(太多)。此外,我会让关闭挂钩保持活动状态一段时间。如果你根本不中断,最后还是不会调用。退出()不会等待1小时睡眠,它只是被杀死。无论如何,我学到了一些关于倒计时锁的知识,干杯!看起来在java8上,挂起不会中断睡眠。无法复制