`

log4j Category.callAppenders Block

    博客分类:
  • JAVA
 
阅读更多

经常在高并发下就遇到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

分享到:
评论
1 楼 无心流泪wan 2018-06-26  
private static final Log log = LogFactory.getLog("xxx"); 
如果采用的log仍然是log4j,仍旧不能解决锁竞争的问题吧?

另外我认为IO瓶颈是线程block的主要原因,并不是因为sychronized的大锁问题

相关推荐

Global site tag (gtag.js) - Google Analytics