如果通过 Control-C 关闭虚拟机,我能否确保计时器启动的线程运行完成?
假设我对以下函数进行了几次调用:
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退出之前运行完成吗?
与此相关的是,关闭钩子是否仅在线程全部退出时才被调用?
Suppose I make a few calls to the following function:
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);
}
My understanding is that a bunch of threads will be running simultaneously at this point.
That is, each timer instance will be spawning short-lived threads at 1-minute intervals.
Suppose I install a shutdown hook (to run when I press Control-C) per the instructions here:
The shutdown hook will cancel all the timers. (Assume that I store the timers in a class-level collection)
Can I guarantee that all the active threads will run to completion before the VM exits?
Related to this, does the shutdown hook only get called when the threads all exit?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当主线程完成或通过 Ctrl+C 发生键盘中断时,关闭钩子就会被调用。
如果要保证活动线程将运行完成,则必须在关闭挂钩中显式
join()
它们。这有点棘手,因为 TimerTask 使用的线程不会直接暴露给您,但您可以在您的类中放置类似的内容:
TimerTask.run()
方法:然后在关闭挂钩中执行类似的操作:
这保证了所有活动线程都将运行完成。然而,这并不一定是个好主意。引用 API文档:
The shutdown hook gets called when either the main thread finishes, or a keyboard interrupt via Ctrl+C occurs.
If you want to guarantee that the active threads will run to completion, you have to explicitly
join()
them in the shutdown hook. This is slightly tricky, since the threads used by theTimerTask
s aren't directly exposed to you, but you could put something like this in your class:And then something like this at the very top of the
TimerTask.run()
method:And then something like this in the shutdown hook:
This guarantees that all the active threads will run to completion. It is, however, not necessarily a good idea. To quote the API documentation: