Mr *_*der 16 java jvm shutdown
当JVM终止与发生什么System.exit(0)或^C或那样的东西吗?我读过"过程刚被吹走"和"每一个线程都被停止"之类的东西,但我想知道究竟发生了什么.我已经知道shutdownHook有些东西仍然会被执行,但是在调用shutdownHooks之前会发生什么,并且在所有这些线程完成之后会发生什么?
我想shutdownHook正确地实现这样一个并且这样做,我需要对可能仍然执行什么和不执行什么做出正确的假设.
一些代码:
class SomeObject {
private boolean stopped;
SomeObject() {
stopped = false;
Thread hook = new Thread() {
@Override
public void run() {
stopped = true;
}
};
hook.setPriority(Thread.MAX_PRIORITY);
Runtime.getRuntime().addShutdownHook(hook);
}
boolean map(Iterator<Object> it) {
while(it.hasNext() && !stopped) {
writeToOtherObject(it.next());
it.remove();
}
//have calculations finished?
return !it.hasNext();
}
}
Run Code Online (Sandbox Code Playgroud)
该map函数计算在其他对象中收集的结果.在所有内容都被分解之前,该对象应该存储在某个文件中(也可以是普通优先级shutdownHook).请问shutdownHook这里有意义吗?据我所知,所有线程首先被销毁,然后shutdownHook才运行(同时,但我假设首先运行高优先级线程......)然后最终确定对象.这使得上面的代码相当无用,因为这样做的目的是shutdownHook确保在关闭已经开始时没有启动新的循环.我的理解是正确和完整的吗?
Rea*_*tic 11
让我们从可以启动关闭序列的不同方式开始:
System.exit()或Runtime.exit().当System.exit(int)被叫时,它会调用Runtime.exit().它检查安全管理器是否允许以给定状态退出,如果是,则调用Shutdown.exit().
如果您中断了JVM或系统向其发送了TERM信号,则默认情况下Shutdown.exit()会直接调用,而无需使用安全管理器进行检查.
该Shutdown班是在内部,包私有类java.lang.除其他外,它有一个exit()和一个halt()方法.它的exit()方法做了一些事情来防止钩子被执行两次,等等,但基本上,它的作用是什么
join在最后为每个线程创建一个.其他系统挂钩可以在应用程序挂钩之前或之后运行.runFinalizersOnExit无论如何都会忽略它.现在,与您的假设相反,在第3阶段,所有线程都停止了.该halt方法是本机的,我没有尝试读取本机代码,但是直到它被调用的那一刻,运行的唯一代码是纯Java,并且没有任何东西可以阻止其中的任何地方的线程.该文件Runtime.addShutdownHook表示,事实上:
关闭钩子只是一个初始化但未启动的线程.当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行.当所有挂钩都完成后,如果启用了finalization-on-exit,它将运行所有未读取的终结器.最后,虚拟机将停止.请注意,守护程序线程将在关闭序列期间继续运行,如果通过调用exit方法启动关闭,则非守护程序线程也将继续运行.
(强调我的)
所以你看,它确实是关闭钩子的工作的一部分,告诉线程他们应该离开他们的循环并清理.
另一个误解是关于给线程一个高优先级.高优先级并不意味着线程将在所有其他挂钩之前首先运行.它只是意味着每当操作系统必须决定哪些线程处于"准备运行"状态以给CPU运行时,高优先级线程将具有更高的"获胜"概率 - 取决于关于操作系统的调度算法.简而言之,它可能会获得更多的CPU访问权限,但它不会 - 特别是如果你有多个CPU核心 - 必须在其他线程之前启动或在它们之前完成.
最后一件事 - 如果你想使用一个标志告诉一个线程停止工作,那个标志应该是volatile.
| 归档时间: |
|
| 查看次数: |
3815 次 |
| 最近记录: |