更新时间:2023-11-09 23:04:46
让我们从可以启动关机序列的不同方式开始:
Let's begin from the different ways the shutdown sequence can be initiated:
System.exit()
或 Runtime.exit()
。System.exit()
or Runtime.exit()
.当调用 System.exit(int)
时,它调用 Runtime.exit ()
。它检查安全管理器是否允许以给定状态退出,如果是,则调用 Shutdown.exit()
。
When System.exit(int)
is called, it calls Runtime.exit()
. It checks with the security manager whether it is permitted to exit with the given status, and if so, calls Shutdown.exit()
.
如果你打断了JVM或系统发送了TERM信号,那么默认情况下,直接调用 Shutdown.exit()
而不检查安全性经理。
If you interrupted the JVM or the system sent it the TERM signal, then by default, Shutdown.exit()
is called directly without checking with the security manager.
Shutdown
类是 java中的内部包私有类。郎
。除其他外,它有一个 exit()
和一个 halt()
方法。它的 exit()
方法会做一些事情来防止钩子被执行两次,依此类推,但基本上,它的作用是
The Shutdown
class is an internal, package-private class in java.lang
. It has, among others, an exit()
and a halt()
methods. Its exit()
method does some stuff to prevent the hooks from being executed twice, and so on, but basically, what it does is
join
。其他系统挂钩可以在应用程序挂钩之前或之后运行。 runFinalizersOnExit
。join
for each of them at the end. Other system hooks may run before or after the application hooks.runFinalizersOnExit
anyway.现在,与您的假设相反,在第3阶段,所有线程都停止了。 halt
方法是原生的,我没有尝试读取本机代码,但是直到它被调用的那一刻,运行的唯一代码是纯Java,并且没有什么可以阻止其中任何地方的线程。 Runtime.addShutdownHook
实际上说:
Now, contrary to your supposition, it is at stage 3 that all the threads are stopped. The halt
method is native, and I have not attempted to read the native code, but up to the moment it is called, the only code being ran is pure Java, and there is nothing that stops the threads anywhere in it. The documentation of Runtime.addShutdownHook
says, in fact:
一个关机钩子只是一个初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。当所有钩子都完成后,如果启用了终止退出,它将运行所有未被发送的终结器。最后,虚拟机将停止。 请注意,守护程序线程将在关闭序列期间继续运行,如果通过调用exit方法启动关闭,则非守护程序线程将继续运行。
(强调我的)
所以你看,确实告诉线程他们应该离开他们的循环确实是关闭钩子的工作的一部分
So you see, it is indeed part of the shutdown hook's job to tell threads that they should leave their loops and clean up.
你的另一个误解就是给线程一个高优先级。高优先级并不意味着线程将在所有其他挂钩之前首先运行。它只是意味着每当操作系统必须决定哪些线程处于准备运行状态以给CPU运行时,高优先级线程将具有更高的获胜概率 - 取决于关于操作系统的调度算法。简而言之,它可能会获得更多的CPU访问权限,但它不会 - 特别是如果你有多个CPU核心 - 必须在其他线程之前启动或在它们之前完成。
Another misconception you have is about giving the thread a high priority. A high priority doesn't mean that the thread will run first, before all other hooks. It merely means that whenever the operating system has to make a decision which of the threads which are in "ready to run" state to give to a CPU to run, a high-priority thread will have a higher probability of "winning" - depending on the operating system's scheduling algorithm. In short, it may get a little more CPU access, but it will not - especially if you have more than one CPU core - necessarily start before other threads or complete before them.
最后一件事 - 如果你想用一个标志告诉一个线程停止工作,那个标志应该是 volatile
。
One last thing - if you want to use a flag to tell a thread to stop working, that flag should be volatile
.