log4j Category.callAppenders Block

阅读更多

经常在高并发下就遇到log4j用错引起的线程block住的问题,看经常遇到问题的代码段如下:

 

public  void callAppenders(LoggingEvent event) {
    int writes = 0;

    for(Category c = this; c != null; c=c.parent) {
      // Protected against simultaneous call to addAppender, removeAppender,...
      synchronized(c) {
	if(c.aai != null) {
	  writes += c.aai.appendLoopOnAppenders(event);
	}
	if(!c.additive) {
	  break;
	}
      }
    }

    if(writes == 0) {
      repository.emitNoAppenderWarning(this);
    }
  }

 在内部会有个同步块,伴随着这个同步块可能会引起一个锁竞争导致cpu感觉像是hang住一样。

 针对这个问题已经有了bug,见  https://issues.apache.org/bugzilla/show_bug.cgi?id=41214

 同时针对这个bug也提出了新的解决方案,使用rw lock。

 

不过如果不升级log4j,在误用的情况下还是会出现这个问题。针对这个说下正确的使用方法,同事给出来最佳使用方法可以避免这个问题,很简单log对象每次使用时都需要是static的,说明白点就是

 

private static final Log log = LogFactory.getLog("xxx");

 

顺便刚好有一篇和log4J 死锁相关的文章

 

Log4j Thread Deadlock - A Case Study

http://java.dzone.com/articles/log4j-thread-deadlock-case

你可能感兴趣的:(log4j Category.callAppenders Block)