java – Log4J 2配置监控和按位比较

一位同事指出了 Log4J 2.3 code的以下片段:
/**
  * Called to determine if the configuration has changed.
  */
 @Override
 public void checkConfiguration() {
     final long current = System.currentTimeMillis();
     if (((counter.incrementAndGet() & MASK) == 0) && (current >= nextCheck)) {
         LOCK.lock();
         try {
             nextCheck = current + intervalSeconds;
             if (file.lastModified() > lastModified) {
                 lastModified = file.lastModified();
                 for (final ConfigurationListener listener : listeners) {
                     final Thread thread = new Thread(new ReconfigurationWorker(listener,reconfigurable));
                     thread.setDaemon(true);
                     thread.start();
                 }
             }
         } finally {
             LOCK.unlock();
         }
     }

其中counter是AtomicInteger字段,MASK设置为0x0f,nextCheck为long.

据我所知,此方法检查是否重新加载配置,但仅当计数器的值可被16整除并且下一个配置检查周期已过时才会这样做.

为什么这是按位和那里?

鉴于对于计数器实例,incrementAndGet是同步的,它可以被认为是“廉价”的限制机制吗?或者也许在“典型”nextCheck周期期间调用checkConfiguration的次数超过必要的次数,因此按位AND作为性能技巧(再次,限制?).

解决方法

是的,这是一种限制机制.在Log4j 2.3中,为每个日志事件调用方法.按位AND表示检查的其余部分仅每16个日志事件执行一次.

正如评论中所指出的那样,在性能提升方面,这是多么有效.对System :: currentTimeMillis的调用不是免费的,并且在极端争用下AtomicLong :: incrementAndGet的性能也是degrades.

由于Log4j 2.5以上代码不再存在(见LOG4J2-89).它已被WatchManager类所取代,该类监视配置文件是否已在后台线程中修改.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...