Shutdown 源码阅读
Shutdown
/**
* 虚拟机关闭步骤
* @since 1.3
*/
class Shutdown {
/* 关闭状态 */
private static final int RUNNING = 0;
private static final int HOOKS = 1;
private static final int FINALIZERS = 2;
private static int state = RUNNING;
/* Should we run all finalizers upon exit? */
private static boolean runFinalizersOnExit = false;
/**
* The system shutdown hooks are registered with a predefined slot.
* The list of shutdown hooks is as follows:
* (0) Console restore hook
* (1) Application hooks
* (2) DeleteOnExit hook
*/
// 最多可注册的钩子函数个数
private static final int MAX_SYSTEM_HOOKS = 10;
private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
// 当前运行钩子的索引
private static int currentRunningHook = 0;
/* The preceding static fields are protected by this lock */
private static class Lock { };
private static Object lock = new Lock();
/* Lock object for the native halt method */
private static Object haltLock = new Lock();
/* Invoked by Runtime.runFinalizersOnExit */
static void setRunFinalizersOnExit(boolean run) {
synchronized (lock) {
runFinalizersOnExit = run;
}
}
/**
* 添加一个关闭钩子
*
* @params slot 目标索引
* @params registerShutdownInProgress 是否允许在关闭过程中注册钩子
* @params hook 待注册的钩子
*/
static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
synchronized (lock) {
// 目标索引处已经注册了
if (hooks[slot] != null) {
throw new InternalError("Shutdown hook at slot " + slot + " already registered");
}
if (!registerShutdownInProgress) {
if (state > RUNNING) {
throw new IllegalStateException("Shutdown in progress");
}
} else {
if (state > HOOKS || state == HOOKS && slot <= currentRunningHook) {
throw new IllegalStateException("Shutdown in progress");
}
}
// 写入钩子
hooks[slot] = hook;
}
}
/**
* 运行所有注册的关闭钩子
*/
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();
}
} catch(final Throwable t) {
if (t instanceof ThreadDeath) {
final ThreadDeath td = (ThreadDeath)t;
throw td;
}
}
}
}
/**
* 强制关闭虚拟机
*/
static void halt(int status) {
synchronized (haltLock) {
halt0(status);
}
}
static native void halt0(int status);
/* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */
private static native void runAllFinalizers();
/**
* 实际的关机顺序定义
*/
private static void sequence() {
synchronized (lock) {
/* Guard against the possibility of a daemon thread invoking exit
* after DestroyJavaVM initiates the shutdown sequence
*/
if (state != HOOKS) {
return;
}
}
// 运行所有的关闭钩子
runHooks();
boolean rfoe;
synchronized (lock) {
state = FINALIZERS;
rfoe = runFinalizersOnExit;
}
// 运行 Finalizers
if (rfoe) {
runAllFinalizers();
}
}
/**
* Invoked by Runtime.exit, which does all the security checks.
*/
static void exit(int status) {
boolean runMoreFinalizers = false;
synchronized (lock) {
if (status != 0) {
runFinalizersOnExit = false;
}
switch (state) {
case RUNNING: /* Initiate shutdown */
state = HOOKS;
break;
case HOOKS: /* Stall and halt */
break;
case FINALIZERS:
if (status != 0) {
/* Halt immediately on nonzero status */
halt(status);
} else {
/* Compatibility with old behavior:
* Run more finalizers and then halt
*/
runMoreFinalizers = runFinalizersOnExit;
}
break;
}
}
if (runMoreFinalizers) {
runAllFinalizers();
halt(status);
}
synchronized (Shutdown.class) {
/* Synchronize on the class object, causing any other thread
* that attempts to initiate shutdown to stall indefinitely
*/
sequence();
halt(status);
}
}
/* Invoked by the JNI DestroyJavaVM procedure when the last non-daemon
* thread has finished. Unlike the exit method, this method does not
* actually halt the VM.
*/
static void shutdown() {
// 修改状态
synchronized (lock) {
switch (state) {
case RUNNING: /* Initiate shutdown */
state = HOOKS;
break;
case HOOKS: /* Stall and then return */
case FINALIZERS:
break;
}
}
// 关机
synchronized (Shutdown.class) {
sequence();
}
}
}
Shutdown 源码阅读的更多相关文章
- 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分
这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...
- ThreadPoolExecutor 源码阅读
目录 ThreadPoolExecutor 源码阅读 Executor 框架 Executor ExecutorService AbstractExecutorService 构造器 状态 Worke ...
- 【详解】ThreadPoolExecutor源码阅读(二)
系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) AQS在W ...
- 【详解】ThreadPoolExecutor源码阅读(一)
系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) 工作原理简 ...
- Caddy源码阅读(二)启动流程与 Event 事件通知
Caddy源码阅读(二)启动流程与 Event 事件通知 Preface Caddy 是 Go 语言构建的轻量配置化服务器.https://github.com/caddyserver/caddy C ...
- Flink源码阅读(一)——Flink on Yarn的Per-job模式源码简析
一.前言 个人感觉学习Flink其实最不应该错过的博文是Flink社区的博文系列,里面的文章是不会让人失望的.强烈安利:https://ververica.cn/developers-resource ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
随机推荐
- vim 去掉自动注释和自动回车
取消 :set paste 恢复 :set paste!
- Galera Cluster 实现mysql的高可用 (Percona XtraDB Cluster)
Galera Cluster 实现mysql的高可用 (Percona XtraDB Cluster) # 基础搭建 # 设备:三台主机 192.168.47.101 192.168.47.102 1 ...
- GitHub的本地与远程
首先要有一个github账户(这不是废话吗) 在linux中先安装git arch linux : pacman -S git 在终端里输入 ssh-keygen ##一直默认就可以了 将公钥加入到G ...
- Scala(二)——基础语法(与Java的区分)和函数式编程
Scala快速入门(二) 一.键盘输入 关于基本类型的运算,以及复制运算,条件运算,运算符等知识,均和Java语言一样,这里不过多叙述. val name = StdIn.readLine() Std ...
- 从零开始学会GAN 0:第一部分 介绍生成式深度学习(连载中)
本书的前四章旨在介绍开始构建生成式深度学习模型所需的核心技术.在第1章中,我们将首先对生成式建模领域进行广泛的研究,并从概率的角度考虑我们试图解决的问题类型.然后,我们将探讨我们的基本概率生成模型的第 ...
- jquery中.each()方法遍历循环如何终止方法
使用return false 终止循环 function checkStar(obj){ var flag=false; //获取本节点星级 var star = obj.getAttribute(& ...
- Python把多行文本合并
在引用论文时,往往格式出错,出现非常多行,这样操作非常不方便.这种方法讲多行合并之后,再处理: # 文件空格和回车键处理工具infile = r'C:\Users\SAM\Desktop\新建文本文档 ...
- Xhorse Condor XC-Mini Plus回顾
Condor是Xhorse生产的最新型电子钥匙切割机.该机器在激光,圆柱和Tibbe键上具有出色的切割性能,几乎可以复制,切割,编码和解码任何汽车钥匙! Condor XC-MINI Plus的亮点: ...
- CSS选择器div和p的用法和区别
div,p.div p.div>p.div+p.div~p.div.a的用法和区别 div,p:选择所有<div>元素和<p>元素 <style> p,spa ...
- isset和empty以及is_null区别
2.empty,isset首先都会检查变量是否存在,然后对变量值进行检测.而is_null 和 “参数本身”只是直接检查变量值,是否为null,因此如果变量未定义就会出现错误! 3.isset():仅 ...