之前对finally的理解是不管是return、break和continue最后finally语句块总是会被执行,但是,最近在看书的过程中发现,有一种情况下,finally会被彻底抛弃和忽略的,这种情况就是在并发程序中,将finally语句块所在的线程(假设为threadFin)设置成后台进程,即threadFin.setDaemon(true);此外,调用后台线程的方法应该是非后台线程的形式,这样,当非后台线程终止结束时,这个方法所调用的后台线程就会被JVM立即关闭,后台线程中的方法将不会去执行finally语句。具体的代码示例如下:
package com.du.concurrent;
import java.util.concurrent.TimeUnit;
public class ADaemon implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
try{
System.out.print("Starting ADaemon");
TimeUnit.MILLISECONDS.sleep(1);
}catch(InterruptedException e){
System.out.print("Exiting via InterruptedException");
}finally{
System.out.print("the finally really run?");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ADaemon ad = new ADaemon();
Thread thread = new Thread(ad);
thread.setDaemon(true); //如果注释掉这行,finally语句块将会执行
thread.start();
}
}
/*
*output
*
*Starting ADaemon
* */
显然,后台进程的关闭是因为main()函数的退出,
即非后台线程的结束而被强制执行的,
所以,这种方式对后台进程的管理是极其不友好的。
非后台的Executor通常是一种更好的方式,
因为Executor控制的所有任务可以被同时关闭(这属于下一个主题了)。