为什么finally块中的语句仍在执行


public class ADaemon implements Runnable {
@Override
public void run() {
try {
System.out.println("Starting ADaemon");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Exiting via InterruptedException");
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}}

结果

Starting ADaemon
Exiting via InterruptedException
This should always run?

我尝试了第4版"Thinking in Java"中的代码示例,但没有得到书中描述的结果,finally块仍在执行中,为什么会这样?顺便说一句,我使用的是oracle jdk 10.0.1。

-------------更新----------------

我的maven runner插件似乎运行了一些东西,我禁用了它,结果和书中描述的一样。

你说书上说:

"最终块可能无法执行">

(添加了强调。(

这并不等同于说:

"最终块将不会执行">

我认为这本书暗示,当应用程序退出时,守护进程线程是否会中断(或其他什么(是未指定的(可能是JVM特定的(。

当然,如果守护进程线程捕获并忽略如下"中断"的异常,那么我会期望finally永远不会被执行。

public class ADaemon implements Runnable {
@Override
public void run() {
try {
System.out.println("Starting ADaemon");
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Caught InterruptedException");
}
}
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}
}

如果守护进程线程没有执行可中断的代码,我会期望类似的行为。

这应该一直运行吗 。除非JVM实际停止,否则保证输入finally块。类似的东西

System.exit(-1);

在CCD_ 3块中将防止这种情况如果那就是你想要的。它还将停止JVM!这本书警告您,如果所有其他线程都完成了,那么在JVM终止之前,守护进程线程可能永远不会被调度。您直接致电start()。考虑使用

SwingUtilities.invokeLater(t);

除非删除t.setDaemon(true);,否则它可能不会运行

finally块是一个强大的(如果使用不当,则很危险(工具,它几乎总是在try或catch块完成后运行(尽管上面突出显示了一些小情况(。看看这个例子:

try{
throw new Exception();
}catch(Exception e){
return;
}finally{
System.out.println("Shouldn't run?");
}

如果这是在一个方法中,finally块将仍然被执行(千万不要这样做,因为这是一种糟糕的做法(。它的设计目的是执行任何清理,而不管您所做的操作(如关闭流(的结果如何(现在可以通过语句"try"中的paranationsis自动完成(。

相关内容

  • 没有找到相关文章

最新更新