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上,挂起不会中断睡眠。无法复制