强制 JVM 在终止之前完成代码块
Posted
技术标签:
【中文标题】强制 JVM 在终止之前完成代码块【英文标题】:Force JVM to finish code block before terminate 【发布时间】:2014-01-27 17:02:10 【问题描述】:我有以下代码:
public class LogWriter implements Runnable
private static BlockingQueue<LogRecord> logQueue;
static
logQueue = new ArrayBlockingQueue<LogRecord>(30);
@Override
public void run()
Integer errorNo = 0;
configureLogger();
while (true)
try
LogRecord record = logQueue.take();
consumeLogRecord(record);
System.out.println(++errorNo + " - Logged error in file '" + LoggerConfig.LOG_PATH + "'");
record = null;
catch (InterruptedException e)
System.out.println(e.getMessage());
这是用 Java 编写的 LibreOffice 插件记录器的一部分。当 LibreOffice 关闭时,它会简单地杀死它的插件(到目前为止,我还不确定),但在向它们发送它正在关闭的信号之前,我可以在我的代码中检测到它(通过 UNO API) .在收到来自 LibreOffice 的终止信号后,我想将我的 LogRecord 队列刷新到日志文件并将 while(true) 更改为 false,以便方法 run() 可以适当地完成,释放它拥有的资源。所以我的问题是,我如何告诉 JVM 等待这个操作是高优先级的,它不应该在完成之前终止?
【问题讨论】:
***.com/questions/5747803/… 关闭钩子是最好的方法 - 你不能强制它们一直工作,但总的来说,它们是你完成这项工作的最佳工具. 如果您知道如何检测代码中的关机信号...究竟是什么问题? 问题是即使 LibreOffice 说它正在关闭,它也不会等待代码来做一些事情,比如关闭文件、释放资源......这就是为什么我问是否在这段代码完成之前,有一种方法可以让 JVM 保持活动状态。 【参考方案1】:关于关闭挂钩的建议必须谨慎对待。关闭挂钩是不得已的设备,您可以在其中尝试通过任何其他方式挽救您无法实现的功能。您不能依赖任何正常的假设,例如 System.out
仍然打开,您的日志文件仍然打开,甚至文件系统可用,等等。
关闭挂钩的一个用例是尝试正常关闭获取的资源,而不尝试进一步的数据传输。
您应该采取的方法是:
告诉自己 LibreOffice 给你的确切条款:你是否有特定的超时时间来完成你的工作?
尽量减少任何时间点的待处理工作,从而最大限度地提高在超时时间内完成工作的机会。
【讨论】:
谢谢,关闭钩子是一个很好的提示,我添加了它作为你所说的最后手段,但是在关闭过程的正确流程中,现在的解决方案是 Java 捕获来自 LibreOffice 的关闭信号, 不允许再向队列中添加任何日志并刷新记录器,从而完成插件。【参考方案2】:你可以使用。
Runtime.getRuntime().addShutdownHook(Thread);
关闭挂钩将是最好的选择。
【讨论】:
以上是关于强制 JVM 在终止之前完成代码块的主要内容,如果未能解决你的问题,请参考以下文章