hha*_*fez 136
来自Sun教程
注意:如果在执行try或catch代码时JVM退出,则finally块可能无法执行.同样,如果执行try或catch代码的线程被中断或终止,则即使应用程序作为一个整体继续,finally块也可能无法执行.
我不知道finally块不会执行的任何其他方式......
Eug*_*ota 62
System.exit关闭虚拟机.
终止当前运行的Java虚拟机.该参数用作状态代码; 按照惯例,非零状态代码表示异常终止.
此方法
exit
在类中调用该方法Runtime
.此方法永远不会正常返回.
try {
System.out.println("hello");
System.exit(0);
}
finally {
System.out.println("bye");
} // try-finally
Run Code Online (Sandbox Code Playgroud)
"bye"不会在上面的代码中打印出来.
小智 49
只是为了扩展其他人所说的内容,任何不会导致JVM退出的事情都将导致finally块.所以方法如下:
public static int Stupid() {
try {
return 0;
}
finally {
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
会奇怪地编译并返回1.
Zar*_*nen 15
与System.exit相关,还存在某些类型的灾难性故障,其中finally块可能无法执行.如果JVM完全耗尽内存,它可能会在没有捕获或最终发生的情况下退出.
具体来说,我记得一个我们愚蠢地试图使用的项目
catch (OutOfMemoryError oome) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为JVM没有剩余的内存来执行catch块.
Tom*_*ine 10
try { for (;;); } finally { System.err.println("?"); }
Run Code Online (Sandbox Code Playgroud)
在这种情况下,finally将不会执行(除非Thread.stop
调用deprecated ,或者通过工具接口等效).
小智 8
这个帖子中的Sun教程被错误地引用了.
注意:如果在执行try或catch代码时JVM退出,则finally块将不会执行.同样,如果执行try或catch代码的线程被中断或终止,则即使应用程序作为一个整体继续,finally块也不会执行.
如果你仔细研究sun教程中的finally块,它不会说"不会执行"但是"可能不会执行"这里是正确的描述
注意:如果在执行try或catch代码时JVM退出,则finally块可能无法执行.同样,如果执行try或catch代码的线程被中断或终止,则即使应用程序作为一个整体继续,finally块也可能无法执行.
这种行为的明显原因是,在运行时系统线程中处理对system.exit()的调用,这可能需要一些时间来关闭jvm,同时线程调度程序可以最终要求执行.因此最终设计为始终执行,但如果您正在关闭jvm,可能会发生jvm在最终执行之前关闭.
此外,如果在try
块内发生死锁/活锁.
这是演示它的代码:
public class DeadLocker {
private static class SampleRunnable implements Runnable {
private String threadId;
private Object lock1;
private Object lock2;
public SampleRunnable(String threadId, Object lock1, Object lock2) {
super();
this.threadId = threadId;
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
try {
synchronized (lock1) {
System.out.println(threadId + " inside lock1");
Thread.sleep(1000);
synchronized (lock2) {
System.out.println(threadId + " inside lock2");
}
}
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
public static void main(String[] args) throws Exception {
Object ob1 = new Object();
Object ob2 = new Object();
Thread t1 = new Thread(new SampleRunnable("t1", ob1, ob2));
Thread t2 = new Thread(new SampleRunnable("t2", ob2, ob1));
t1.start();
t2.start();
}
}
Run Code Online (Sandbox Code Playgroud)
此代码生成以下输出:
t1 inside lock1
t2 inside lock1
Run Code Online (Sandbox Code Playgroud)
并且"终于"永远不会被打印出来
以下是一些可以绕过finally块的条件:
最后一个非守护程序线程退出示例:
public class TestDaemon {
private static Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Is alive");
Thread.sleep(10);
// throw new RuntimeException();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.out.println("This will never be executed.");
}
}
};
public static void main(String[] args) throws InterruptedException {
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
daemon.start();
Thread.sleep(100);
// daemon.stop();
System.out.println("Last non-daemon thread exits.");
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
73356 次 |
最近记录: |