gpt4 book ai didi

Java - 如何让记录器在关闭 Hook 中工作?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:43:41 26 4
gpt4 key购买 nike

我有一个专门的记录器类,它使用 java.util.logging.Logger 类。我希望能够在另一个类的关闭 Hook 中使用这个记录器。但是,它似乎没有在关机时登录。根据我的阅读,可能已经为导致问题的记录器本身激活了一个关闭 Hook 。

我怎样才能让它发挥作用?理想情况下,我希望在日志文件中看到我确实在进程终止时执行了关闭 Hook 。

最佳答案

再次查看源代码,解决方案似乎是定义一个系统属性 java.util.logging.manager,它是 LogManager 的子类,覆盖了 reset(); 方法,以便 Loggers 在关闭时继续工作。

import java.util.logging.LogManager;
import java.util.logging.Logger;

public class Main {
static {
// must be called before any Logger method is used.
System.setProperty("java.util.logging.manager", MyLogManager.class.getName());
}

public static class MyLogManager extends LogManager {
static MyLogManager instance;
public MyLogManager() { instance = this; }
@Override public void reset() { /* don't reset yet. */ }
private void reset0() { super.reset(); }
public static void resetFinally() { instance.reset0(); }
}

public static void main(String... args) {
Logger logger1 = Logger.getLogger("Main1");
logger1.info("Before shutdown");
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
try {
Logger logger2 = Logger.getLogger("Main2");
logger2.info("Shutting down 2");

} finally {
MyLogManager.resetFinally();
}
}
}));
}
}

打印

Dec 11, 2012 5:56:55 PM Main main
INFO: Before shutdown
Dec 11, 2012 5:56:55 PM Main$1 run
INFO: Shutting down 2

从 LogManager 的这段代码中,您可以看到有一个关闭 Hook 可以拆除处理程序并关闭它们。如果以前未使用过记录器,则记录器仅在关闭时工作,因此不会运行此代码。

// This private class is used as a shutdown hook.
// It does a "reset" to close all open handlers.
private class Cleaner extends Thread {

private Cleaner() {
/* Set context class loader to null in order to avoid
* keeping a strong reference to an application classloader.
*/
this.setContextClassLoader(null);
}

public void run() {
// This is to ensure the LogManager.<clinit> is completed
// before synchronized block. Otherwise deadlocks are possible.
LogManager mgr = manager;

// If the global handlers haven't been initialized yet, we
// don't want to initialize them just so we can close them!
synchronized (LogManager.this) {
// Note that death is imminent.
deathImminent = true;
initializedGlobalHandlers = true;
}

// Do a reset to close all active handlers.
reset();
}
}


/**
* Protected constructor. This is protected so that container applications
* (such as J2EE containers) can subclass the object. It is non-public as
* it is intended that there only be one LogManager object, whose value is
* retrieved by calling Logmanager.getLogManager.
*/
protected LogManager() {
// Add a shutdown hook to close the global handlers.
try {
Runtime.getRuntime().addShutdownHook(new Cleaner());
} catch (IllegalStateException e) {
// If the VM is already shutting down,
// We do not need to register shutdownHook.
}
}

来 self 自己的测试

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
try {
Logger logger2 = Logger.getLogger("Main2");
logger2.info("Shutting down 2");
} catch (Throwable t) {
t.printStackTrace();
}
}
}));

打印

Dec 11, 2012 5:40:15 PM Main$1 run
INFO: Shutting down 2

但是如果你添加

Logger logger1 = Logger.getLogger("Main1");

在这个街区之外你什么也得不到。

关于Java - 如何让记录器在关闭 Hook 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13825403/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com