mer*_*011 1 java command-line control-c java-6
假设我对以下函数进行了几次调用:
 public void StartTimedRuns(){
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask(){
        public void run(){
            //do something that takes less than a minute
        }
    }, 0, 60*1000);
 }
我的理解是,此时会有一堆线程同时运行.也就是说,每个计时器实例将以1分钟的间隔生成短期线程.
假设我按照以下说明安装了一个关闭钩子(按下Control-C时运行):
关闭挂钩将取消所有计时器.(假设我将计时器存储在类级别的集合中)
我可以保证在VM退出之前所有活动线程都将运行完成吗?
与此相关,只有在线程全部退出时才会调用shutdown钩子吗?
当主线程完成或通过Ctrl + C发生键盘中断时,将调用shutdown hook.
如果要保证活动线程将运行完成,则必须join()在shutdown hook中明确它们.这有点棘手,因为TimerTasks 使用的线程并没有直接暴露给你,但你可以在你的类中放置这样的东西:
private static List<Thread> timerThreads = new LinkedList<Thread>();
然后在TimerTask.run()方法的最顶端这样的事情:
timerThreads.add(Thread.currentThread());
然后在关闭钩子中这样的事情:
try {
    for (Thread t : timerThreads) {
        t.join();
    }
} catch (InterruptedException e) {
    // handle it somehow
}
这可以保证所有活动线程都将运行完成.然而,这不一定是个好主意.引用API文档:
关闭挂钩在虚拟机的生命周期中的微妙时间运行,因此应该进行防御性编码.特别是它们应该被编写为线程安全的并且尽可能避免死锁.[...]关机挂钩也应该快速完成工作.当程序调用
exit期望时,虚拟机将立即关闭并退出.当虚拟机因用户注销或系统关闭而终止时,底层操作系统可能只允许一段固定的时间来关闭和退出.因此,不建议尝试任何用户交互或在关闭钩子中执行长时间运行的计算.
| 归档时间: | 
 | 
| 查看次数: | 955 次 | 
| 最近记录: |