加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 从静态最终变量初始化器获取Logger是否有效?

发布时间:2020-12-15 00:43:38 所属栏目:Java 来源:网络整理
导读:我们有很多类代码,它们有一些如下所示的样板: private static Logger logger = null;private static Logger getLogger() { if (logger == null) { logger = Logger.getLogger(MyClass.class); } return logger;} 这个想法是类可以将调试内容记录到Logger中.
我们有很多类代码,它们有一些如下所示的样板:
private static Logger logger = null;

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

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

关于这种模式,有几件我不喜欢的事情.首先,单例getLogger()不同步并同步它,而正确会无缘无故地给每个后续调用带来负担.

我真的希望能够将其压缩到这样:

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

然后我可以直接引用记录器,甚至不用单独的getter.

我担心的问题是,通过这样做,即使从未调用过记录器,我也会在加载类时创建一个Logger.我有10,000个奇怪的类都调用了getLogger(),所以我实际上在这里创建了多少个Logger实例?如果我的log4j属性包含一些appender,我只是一遍又一遍地引用相同的记录器,或者我是在创建10,000个这样的东西?

解决方法

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

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

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

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

这样,Logger的实例将仅在第一次getLogger调用时创建. (这种技术称为初始化按需持有者(IODH),它是线程安全的,并且没有同步开销).

我可以给你一个offtopic建议吗?考虑将Log4J替换为SLF4J Logback库的组合.它们是由同一个作者编写的,并描述为“流行的log4j项目的继承者,在log4j离开的地方”.您可以在this SO thread阅读更多内容.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读