【问题标题】:Force JVM to finish code block before terminate强制 JVM 在终止之前完成代码块
【发布时间】: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 等待这个操作是高优先级的,它不应该在完成之前终止?

【问题讨论】:

  • 关闭钩子是最好的方法 - 你不能强制它们一直工作,但总的来说,它们是你完成这项工作的最佳工具.
  • 如果您知道如何检测代码中的关机信号...究竟是什么问题?
  • 问题是即使 LibreOffice 说它正在关闭,它也不会等待代码来做一些事情,比如关闭文件、释放资源......这就是为什么我问是否在这段代码完成之前,有一种方法可以让 JVM 保持活动状态。

标签: java multithreading libreoffice


【解决方案1】:

关于关闭挂钩的建议必须谨慎对待。关闭挂钩是不得已的设备,您可以在其中尝试通过任何其他方式挽救您无法实现的功能。您不能依赖任何正常的假设,例如 System.out 仍然打开,您的日志文件仍然打开,甚至文件系统可用,等等。

关闭挂钩的一个用例是尝试正常关闭获取的资源,而不尝试进一步的数据传输。

应该采取的方法是:

  1. 告诉自己 LibreOffice 给你的确切条款:你是否有特定的超时时间来完成你的工作?

  2. 尽量减少任何时间点的待处理工作,从而最大限度地提高在超时时间内完成工作的机会。

【讨论】:

  • 谢谢,关闭钩子是一个很好的提示,我添加了它作为你所说的最后手段,但是在关闭过程的正确流程中,现在的解决方案是 Java 捕获来自 LibreOffice 的关闭信号, 不允许再向队列中添加任何日志并刷新记录器,从而完成插件。
【解决方案2】:

你可以使用。

Runtime.getRuntime().addShutdownHook(Thread);

关闭挂钩将是最好的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2016-10-09
    相关资源
    最近更新 更多