http://www.cnblogs.com/luochengor/archive/2011/08/11/2134818.html
这篇文章应该是Thinking in Java 中文版中的一段,关于线程-守护线程(Daemon Thread)的介绍
可能是我理解de不好,我对书对于daemon thread 中的finally是否执行的介绍有点迷糊了,故自己写个方法测试之后才搞明白。
就拿书中的例子做进一步说明。先来看下原文:不看我的罗嗦,可以直接看文章结尾的结论。
import java.util.concurrent.TimeUnit; /** * Finally shoud be always run ? */ public class DaemonsDontRunFinally { public static void main(String[] args) { Thread t = new Thread(new ADaemon()); t.setDaemon(true); t.start(); } } class ADaemon implements Runnable { public void run() { try { System.out.println("start ADaemon..."); TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { System.out.println("Exiting via InterruptedException"); } finally { System.out.println("This shoud be always run ?"); } } }
运行结果:
start ADaemon...
如果将main函数中的t.setDaemon(true);注释掉,运行结果如下:
start ADaemon...
This shoud be always run ?
-----------------------------------------------------------------------
而我实际运行的结果不是这样的,实际是:
t 是 daemon 线程时,什么都不输出
t 不是daemon 线程时,输出
start ADaemon...
This shoud be always run ?
看完书中所述,给我的理解是daemon线程类中的finally代码块都不会得到执行(当然我对此是怀疑的)
开始测试,我让main方法结束前 sleep 10秒,看到当t是守护线程时,finally的代码块是执行的。
继续测试,我让main方法结束前sleep 1秒,finally的代码块也是不执行的(daemon 线程也是sleep 1秒)
所以我得到以下结论:
runnable实现类中的run方法中如果含有finally代码块,如果执行该类实例的线程是守护线程(daemon thread),finally代码块有可能是不会得到执行的,但也有可能会执行,
那就是文中提到的 如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了,finally代码块即可能没有机会执行了。
所以守护线程中一般不要去对文件、数据库、网络等资源进行操作,以免资源文件来不及释放,造成死锁。