Java 中关闭挂钩的有用示例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2921945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Useful example of a shutdown hook in Java?
提问by Jason S
I'm trying to make sure my Java application takes reasonable steps to be robust, and part of that involves shutting down gracefully. I am reading about shutdown hooksand I don't actually get how to make use of them in practice.
我试图确保我的 Java 应用程序采取合理的步骤来保持健壮,其中一部分涉及正常关闭。我正在阅读有关关闭挂钩的信息,但实际上我不知道如何在实践中使用它们。
Is there a practical example out there?
有实际的例子吗?
Let's say I had a really simple application like this one below, which writes numbers to a file, 10 to a line, in batches of 100, and I want to make sure a given batch finishes if the program is interrupted. I get how to register a shutdown hook but I have no idea how to integrate that into my application. Any suggestions?
假设我有一个非常简单的应用程序,如下所示,它将数字写入文件,将 10 个写入一行,以 100 个为一组,如果程序中断,我想确保给定的批处理完成。我知道如何注册关闭挂钩,但我不知道如何将其集成到我的应用程序中。有什么建议?
package com.example.test.concurrency;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
public class GracefulShutdownTest1 {
final private int N;
final private File f;
public GracefulShutdownTest1(File f, int N) { this.f=f; this.N = N; }
public void run()
{
PrintWriter pw = null;
try {
FileOutputStream fos = new FileOutputStream(this.f);
pw = new PrintWriter(fos);
for (int i = 0; i < N; ++i)
writeBatch(pw, i);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
finally
{
pw.close();
}
}
private void writeBatch(PrintWriter pw, int i) {
for (int j = 0; j < 100; ++j)
{
int k = i*100+j;
pw.write(Integer.toString(k));
if ((j+1)%10 == 0)
pw.write('\n');
else
pw.write(' ');
}
}
static public void main(String[] args)
{
if (args.length < 2)
{
System.out.println("args = [file] [N] "
+"where file = output filename, N=batch count");
}
else
{
new GracefulShutdownTest1(
new File(args[0]),
Integer.parseInt(args[1])
).run();
}
}
}
采纳答案by aioobe
You could do the following:
您可以执行以下操作:
- Let the shutdown hook set some AtomicBoolean (or volatile boolean) "keepRunning" to false
- (Optionally,
.interrupt
the working threads if they wait for data in some blocking call) - Wait for the working threads (executing
writeBatch
in your case) to finish, by calling theThread.join()
method on the working threads. - Terminate the program
- 让关闭钩子将一些 AtomicBoolean(或 volatile boolean)“keepRunning”设置为 false
- (可选,
.interrupt
如果工作线程在某些阻塞调用中等待数据) writeBatch
通过调用Thread.join()
工作线程上的方法,等待工作线程(在您的情况下执行)完成。- 终止程序
Some sketchy code:
一些粗略的代码:
- Add a
static volatile boolean keepRunning = true;
In run()you change to
for (int i = 0; i < N && keepRunning; ++i) writeBatch(pw, i);
In main()you add:
final Thread mainThread = Thread.currentThread(); Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { keepRunning = false; mainThread.join(); } });
- 添加一个
static volatile boolean keepRunning = true;
在run() 中,您更改为
for (int i = 0; i < N && keepRunning; ++i) writeBatch(pw, i);
在main() 中添加:
final Thread mainThread = Thread.currentThread(); Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { keepRunning = false; mainThread.join(); } });
That's roughly how I do a graceful "reject all clients upon hitting Control-C" in terminal.
这大致是我如何在终端中优雅地“在点击 Control-C 时拒绝所有客户端”。
From the docs:
从文档:
When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt.
当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。当所有钩子都完成后,如果启用了退出时终结,它将运行所有未调用的终结器。最后,虚拟机将停止。
That is, a shutdown hook keeps the JVM running until the hook has terminated (returned from the run()-method.
也就是说,关闭钩子保持 JVM 运行,直到钩子终止(从run()方法返回。
回答by satish
Shutdown Hooks are unstarted threads that are registered with Runtime.addShutdownHook().JVM does not give any guarantee on the order in which shutdown hooks are started.For more info refer http://techno-terminal.blogspot.in/2015/08/shutdown-hooks.html
Shutdown Hooks 是使用 Runtime.addShutdownHook() 注册的未启动线程。JVM 不保证关闭 hooks 的启动顺序。有关更多信息,请参阅http://techno-terminal.blogspot.in/2015/08 /shutdown-hooks.html