假设场景:
我有一个守护线程负责一些I/O,主线程完成并返回,JVM决定终止我的守护线程。
它是如何做到的呢?打断?最终确定?如何编写守护程序线程的代码,使其在终止时正常响应?
发布于 2011-12-29 01:51:51
我只是写了以下代码作为测试:
public class DaemonThreadPlay {
public static void main(String [] args) {
Thread daemonThread = new Thread() {
public void run() {
while (true) {
try {
System.out.println("Try block executed");
Thread.sleep(1000l);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
@Override
public void finalize() {
System.out.println("Finalize method called");
}
};
daemonThread.setDaemon(true);
daemonThread.start();
try {
Thread.sleep(2500l);
} catch (Throwable t) {
//NO-OP
}
}
}
我将断点放在守护线程的catch块和finalize方法中。即使执行了try块,也未到达这两个断点。显然,这段代码有同步/计时问题,但我认为我们可以有把握地得出结论,守护进程线程在关闭时不会中断,也不一定要调用它们的finalize()方法。
您总是可以向JVM运行时添加一个关闭钩子:
Thread shutdownHook = ... // construct thread that somehow
// knows about all the daemon threads
Runtime.getRuntime().addShutdownHook(shutdownHook);
显然,您的shutdown钩子可以执行“优雅”关机所需的任何任务。
发布于 2013-08-28 21:18:41
我想你误解了守护线程是什么。
请参阅what is a daemon thread in java
总而言之,这基本上意味着守护程序线程不应该执行任何I/O或持有任何资源。如果您违反了这个基本规则,那么您的线程就不符合成为守护线程的条件。
添加关闭钩子是确保代码在JVM终止之前被调用的标准方法,但即使这样也不能100%保证-例如,您的JVM可能会崩溃,让操作系统以保护操作系统的方式清理资源,但很可能会使应用程序处于不一致/错误的状态。
系统检查点和恢复机制可以追溯到软件的早期(例如操作系统和批处理操作),不幸的是,这个轮子不断被重新发明,因为没有“银弹”方法(API)以足够通用的方式解决这个问题。
发布于 2011-12-29 02:08:40
AFAIK,守护进程线程并不是真正用于主流I/O工作。如果所有线程都完成了,JVM可能会突然关闭所有守护进程线程。针对您需求的可能解决方法是创建一个如下所示的ExecutorService:
ExecutorService execPool = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
从shutdown钩子调用executorservice Shutdown方法。
Runtime.getRuntime().addShutdownHook(....)
https://stackoverflow.com/questions/8663107
复制相似问题