对于类为Thread的shutdown钩子是在调用shutdown的线程上运行其可运行代码,还是在其自身上运行,存在一些冲突。
addShutdown Hook
将Thread
作为参数。这意味着线程将启动并在自己身上运行其run
方法。这也与addShutdown Hook
的留档一致:
公共void addShutdownHook(线程挂钩)
注册新的虚拟机关闭挂钩。Java虚拟机关闭以响应两种事件:
关闭钩子只是一个初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有注册的关闭挂钩,并让它们同时运行。当所有钩子完成后,如果启用了退出时的终结,那么它将运行所有未调用的终结器。最后,虚拟机将停止。注意,守护进程线程将在关闭序列期间继续运行,如果通过调用exit方法启动关闭,则非守护进程线程也将继续运行。
(强调矿山)
但是,代码如下:
/* Run all registered shutdown hooks
*/
private static void runHooks() {
for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
try {
Runnable hook;
synchronized (lock) {
// acquire the lock to make sure the hook registered during
// shutdown is visible here.
currentRunningHook = i;
hook = hooks[i];
}
if (hook != null) hook.run(); // not Thread.start - Runnable.run (!!)
} catch(Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
throw td;
}
}
}
}
(!!
评论我的)
注意,这与JDK 6相比变化不大,这使问题更加清楚:
/* Run all registered shutdown hooks
*/
private static void runHooks() {
/* We needn't bother acquiring the lock just to read the hooks field,
* since the hooks can't be modified once shutdown is in progress
*/
for (Runnable hook : hooks) {
try {
hook.run();
} catch(Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
throw td;
}
}
}
}
起初我以为我读错了,调用run
神奇地启动了线程。但事实并非如此。我自己编写了run
代码。该代码不会启动线程(在Thread
的情况下,假设run
在线程上运行是自然和正确的。)
所以这里确实出了点问题。它是Javadoc和addShutdownHook方法的签名吗?每个代码都不应该采用线程,而是可运行的?这是实施吗?还是更可能的罪魁祸首——我;如果是这样,怎么做?
您混淆了Shutdown.runHooks()
和Application Shutdown Hooks.runHooks()
。您在Runtime
中注册的关闭挂钩在Application ationShutdown Hooks
中注册,它本身将Runnable
注册为Shutdown
挂钩
static {
try {
Shutdown.add(1 /* shutdown hook invocation order */,
false /* not registered if shutdown in progress */,
new Runnable() {
public void run() {
runHooks(); // (!!) your hooks
}
}
);
hooks = new IdentityHashMap<>();
} catch (IllegalStateException e) {
// application shutdown hooks cannot be added if
// shutdown is in progress.
hooks = null;
}
}
同时运行关闭挂钩
static void runHooks() { // In ApplicationShutdownHooks
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
hooks = null;
}
for (Thread hook : threads) { // (!!) your hooks
hook.start();
}
for (Thread hook : threads) {
try {
hook.join();
} catch (InterruptedException x) { }
}
}
作为参考,Runtime#addShutdown Hook(Thread)
的(oracle jdk7)代码。
public void addShutdownHook(Thread hook) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("shutdownHooks"));
}
ApplicationShutdownHooks.add(hook);
}
比如说老年代,青年代,永久代,伊甸区,还有垃圾回收的策略,JVM内存结构等等,我不要第三方的资料,我要官方的资料,请问哪里有?
译者注: 原英文文档地址为 https://linkerd.io/docs/ 欢迎来到 linkerd! 本文档将帮助您开始使用。 它分为几个主要部分: 概述:以 high-level 的方式介绍 linkerd 的特性,解释其背后的理由,并介绍文档其余内容中使用的重要概念。 开始:提供在各种环境中设置和运行 linkerd 的具体说明。从这里开始快速入门。 特性:涵盖 linkerd 的主要功能
译注 原英文文档地址为 https://istio.io/docs/ 正文 欢迎来到Istio。 欢迎来到Istio的最新文档主页。从这里您可以通过以下链接了解有关Istio的所有信息: 概念 概念解释了Istio的一些关键点。在这里您可以了解Istio的工作原理及其实现。 安装 在不同的环境下(如Kubernetes、Consul等)安装Istio控制平面,以及在应用程序部署中安装sidecar
欢迎来到 Sublime Text 编辑器的非官方文档。Sublime Text 是一个可以运行在 OS X、Windows 和 Linux 上的多功能编辑器,你可以用它来写代码或是写散文。
Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。你可以在它的主页上看到许多精采的演示。 在线示例:https://www.wenjiangs.com/wp-content/uploads/three.js/examples/ 在线编辑器:https://www.wenjiangs.com/wp-content/uploads/t
Flarum 是一款非常简洁的开源论坛软件。它响应快速、简便易用,拥有打造一片成功的社区所需的所有功能。本用户指南将帮助您使用 Flarum 搭建自己的论坛,并教授您管理社区的基础知识。