gpt4 book ai didi

java - 从静态最终变量初始值设定项获取 Logger 是否有效?

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

我们有很多类代码,其中有一些样板,如下所示:

private static Logger logger = null;

private static Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(MyClass.class);
}
return logger;
}

这个想法是类可以将调试内容记录到记录器中。需要记录某些内容的第一个代码调用 getLogger() 并使记录器存在。

这个模式有几点我不喜欢。首先,单例 getLogger() 未同步并同步它,而正确会无缘无故地给每个后续调用带来负担。

我真的很想把它浓缩成这样:

private static final Logger logger = Logger.getLogger(MyClass.class);

然后我就可以直接引用记录器,甚至不用为单例 getter 而烦恼。

我担心的问题是,这样做会导致在加载类时创建一个记录器,即使记录器从未被调用也是如此。我有 10,000 多个奇怪的类都调用 getLogger(),那么我实际上在这里创建了多少个 Logger 实例?如果我的 log4j 属性包含一些附加程序,我只是一遍又一遍地引用同一个记录器,还是我正在创建 10,000 个这样的东西?

最佳答案

如果您使用默认的 Log4j 配置(即默认的 LoggerRepository、DefaultCategoryFactory 等),那么您将创建 10'000 个 Logger 实例。他们消耗多少内存?除了上帝和你的 Profiler 之外没有人知道这一点。 (我猜只有后者会告诉你这一点)。

如果内存占用对您的环境来说太多,请将 Logger 初始化移动到静态内部类,如下所示:

static class LoggerHolder {
static Logger logger = Logger.getLogger(MyClass.class);
}

private static Logger getLogger() {
return LoggerHolder.logger;
}

那样的话,Logger 的实例只会在第一次调用 getLogger 时创建。 (这种技术被称为 Initialization On Demand Holder (IODH),它是线程安全的并且同步开销为零)。

我可以给你一个离题建议吗?考虑用 SLF4J 的组合替换 Log4J + Logback图书馆。它们由同一作者编写,并被描述为“流行的 log4j 项目的继任者,接续 log4j 的发展”。您可以在 this SO thread 中阅读更多内容.

关于java - 从静态最终变量初始值设定项获取 Logger 是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7318934/

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