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自动完成(。