Java关闭挂钩– Runtime.addShutdownHook()

Java shutdown hook are handy to run some code when program exit. We can use java.lang.Runtime.addShutdownHook(Thread t) method to add a shutdown hook in the JVM.

程序退出时,使用Java shutdown钩子可以方便地运行一些代码。 我们可以使用java.lang.Runtime.addShutdownHook(Thread t)方法在JVM中添加一个关闭钩子。

Java关闭挂钩 (Java shutdown hook)

Java shutdown hook runs in these two cases.

在这两种情况下,将运行Java shutdown挂钩。

  1. The program exits normally, or we call System.exit() method to terminate the program. Read more about Java System Class.

    该程序正常退出,或者我们调用System.exit()方法终止该程序。 阅读有关Java System Class的更多信息。
  2. User interrupts such as Ctrl+C, system shutdown etc.

    用户中断,例如Ctrl + C,系统关闭等。

Important points about Java Shutdown Hook are;

有关Java Shutdown Hook的要点是:

  1. We can add multiple shutdown hooks using Runtime addShutdownHook() method.

    我们可以使用Runtime addShutdownHook()方法添加多个关闭挂钩。
  2. Shutdown hooks are initialized but not-started threads. They start when JVM shutdown triggers.

    关机挂钩是已初始化但未启动的线程 。 它们在JVM关闭触发时启动。
  3. We can’t determine the order in which shutdown hooks will execute, just like multiple threads executions.

    我们无法确定关闭挂钩的执行顺序,就像执行多个线程一样。
  4. All un-invoked finalizers are executed if finalization-on-exit has been enabled.

    如果启用了退出时终结,则将执行所有未调用的终结器。
  5. There is no guarantee that shutdown hooks will execute, such as system crash, kill command etc. So you should use it only for critical scenarios such as making sure critical resources are released etc.

    无法保证关机钩子会执行,例如系统崩溃,kill命令等。因此,应仅将其用于紧急情况下,例如确保释放关键资源等。
  6. You can remove a hook using Runtime.getRuntime().removeShutdownHook(hook) method.

    您可以使用Runtime.getRuntime().removeShutdownHook(hook)方法删除钩子。
  7. Once shutdown hooks are started, it’s not possible to remove them. You will get IllegalStateException.

    启动关闭挂钩后,将无法删除它们。 您将获得IllegalStateException
  8. You will get SecurityException if security manager is present and it denies RuntimePermission("shutdownHooks").

    如果存在安全管理器并且拒绝RuntimePermission("shutdownHooks")则将获得SecurityException。

Java关闭挂钩示例 (Java shutdown hook example)

So let’s see example of shutdown hook in java. Here is a simple program where I am reading a file line by line from some directory and processing it. I am having program state saved in a static variable so that shutdown hook can access it.

因此,让我们来看一下Java中的shutdown hook的示例。 这是一个简单的程序,其中我从某个目录中逐行读取文件并进行处理。 我将程序状态保存在静态变量中,以便关机挂钩可以访问它。

package com.journaldev.shutdownhook;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;

public class FilesProcessor {

	public static String status = "STOPPED";
	public static String fileName = "";

	public static void main(String[] args) {
		String directory = "/Users/pankaj/temp";
		Runtime.getRuntime().addShutdownHook(new ProcessorHook());
		File dir = new File(directory);

		File[] txtFiles = dir.listFiles(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				if (name.endsWith(".txt"))
					return true;
				else
					return false;
			}
		});

		for (File file : txtFiles) {
			System.out.println(file.getName());
			BufferedReader reader = null;
			status = "STARTED";
			fileName = file.getName();
			try {
				FileReader fr = new FileReader(file);
				reader = new BufferedReader(fr);
				String line;

				line = reader.readLine();

				while (line != null) {
					System.out.println(line);
					Thread.sleep(1000); // assuming it takes 1 second to process each record
					// read next line
					line = reader.readLine();
				}
				status = "PROCESSED";
			} catch (IOException | InterruptedException e) {
				status = "ERROR";
				e.printStackTrace();
			}finally{
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		status="FINISHED";
	}

}

Most important part of above code is line no 16 where we are adding the shutdown hook, below is the implementation class.

上面代码中最重要的部分是第16行,我们在其中添加了shutdown钩子,下面是实现类。

package com.journaldev.shutdownhook;

public class ProcessorHook extends Thread {

	@Override
	public void run(){
		System.out.println("Status="+FilesProcessor.status);
		System.out.println("FileName="+FilesProcessor.fileName);
		if(!FilesProcessor.status.equals("FINISHED")){
			System.out.println("Seems some error, sending alert");
		}
		
	}
}

It’s a very simple use, I am just logging state when the shutdown hook started and if it was not finished already, then send an alert (Not actually, its just logging here).

这是一种非常简单的用法,我只是在记录关闭挂钩开始时的状态,如果还没有完成,则发送警报(实际上不是在这里记录它)。

Let’s see some program execution through terminal.

让我们看看通过终端执行一些程序。

  1. Program terminated using Ctrl+C command.

    As you can see in the above image, shutdown hook started executing as soon as we tried to kill the JVM using Ctrl+C command.

    如上图所示,当我们尝试使用Ctrl + C命令杀死JVM时,shutdown挂钩就开始执行。

  2. Program executed normally.

    Notice that hook is called in case of normal exit too, and it’s printing status as finished.

    请注意,如果在正常退出的情况下也调用了钩子,则其打印状态为完成。

  3. Kill Command to terminate JVM.

    I used two terminal windows to fire kill command to the java program, so operating system terminated the JVM and in this case shutdown hook was not executed.

    我使用了两个终端窗口向Java程序发射kill命令,因此操作系统终止了JVM,在这种情况下,未执行关闭钩子。

That’s all for shutdown hook in java, I hope you learned about JVM shutdown hooks and might find a use for it.

这就是Java中的关闭钩子,我希望您了解了JVM关闭钩子,并可能会找到用处。

Reference: API Doc

参考: API文档

翻译自: https://www.journaldev.com/9113/java-shutdown-hook-runtime-addshutdownhook

引用和介绍了使用Java中的Runtime.getRuntime().addShutdownHook()方法来添加关闭钩子。关闭钩子是一个已经初始化但尚未启动的线程,当JVM关闭时会执行这些钩子。关闭钩子可以在JVM关闭时执行一些内存清理和资源回收等工作。引用中也提到了这个方法,并指出当程序正常退出、系统调用System.exit方法或虚拟机被关闭时,才会执行添加的shutdownHook线程。 因此,使用Runtime.getRuntime().addShutdownHook()方法可以在Java程序关闭时执行一些必要的清理工作,以确保程序的正常退出和资源的释放。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [thrift服务端和客户端实现Nifty.zip](https://download.csdn.net/download/weixin_39841856/11384893)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [高并发编程-Runtime.getRuntime().addShutdownHook为自己的应用添加hook](https://blog.csdn.net/yangshangwei/article/details/102583944)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [runtime.getruntime().addshutdownhook](https://blog.csdn.net/Iccmo/article/details/71107697)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值