Log4J 2配置监控和按位比较

Ale*_*lex 7 java logging java.util.concurrent log4j2

一位同事从Log4J 2.3代码中指出了以下片段:

/**
  * 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();
         }
     }
Run Code Online (Sandbox Code Playgroud)

哪里counter是一个AtomicInteger字段,MASK被设置为0x0fnextChecklong.

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

为什么这是按位和那里?

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

Rem*_*pma 0

是的,这是一种节流机制。在 Log4j 2.3 中,每个日志事件都会调用此方法。按位 AND 意味着检查的其余部分仅每 16 个日志事件执行一次。

正如评论中所指出的,这对于性能增益的效果如何是有争议的。对 的调用System::currentTimeMillis不是免费的,并且在严重争用的情况下AtomicLong::incrementAndGet性能也会下降

自 Log4j 2.5 起,上述代码不再存在(请参阅LOG4J2-89)。它已被WatchManager类取代,该类监视配置文件是否在后台线程中被修改。