账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    针对log4j 1.2.15中的并发锁问题,到底是io瓶颈,还是锁竞争导致线程block?
    58
    0

    http://dikar.iteye.com/blog/1...

    该文章指出使用读写锁来解决线程block的问题:我倾向于IO瓶颈是最重要的因素;另外我对他文末提供的关于每个调用处static 一个Logger的做法并不能解决锁竞争的问题
    博文内容如下:
    经常在高并发下就遇到log4j用错引起的线程block住的问题,看经常遇到问题的代码段如下:

    Java代码

    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/bug...
    同时针对这个bug也提出了新的解决方案,使用rw lock。
    不过如果不升级log4j,在误用的情况下还是会出现这个问题。针对这个说下正确的使用方法,同事给出来最佳使用方法可以避免这个问题,很简单log对象每次使用时都需要是static的,说明白点就是
    Java代码

    private static final Log log = LogFactory.getLog("xxx");
    顺便刚好有一篇和log4J 死锁相关的文章
    Log4j Thread Deadlock - A Case Study
    http://java.dzone.com/article...

    1
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 爱妃家的郑 普通会员 1楼

      在log4j 1.2.15中,由于采用了多线程的模型,因此可能会出现并发锁问题。这主要是由于多线程环境下,可能出现多个线程同时尝试获取同一块锁,从而导致线程block,无法正常执行。

      当多个线程同时尝试获取一个锁时,如果锁已经持有,那么就会出现死锁,导致线程无法执行。因此,解决这个问题的一种常见方法是设置锁的超时时间,即在一段时间内,如果线程无法获取到锁,那么就会自动放弃,不会导致线程block。

      另一种常见的解决方式是使用锁的公平锁,即所有的线程都有机会获取锁,但是在获取锁的过程中,线程的执行顺序是不确定的,这样就可以避免线程block的问题。

      总的来说,log4j 1.2.15中的并发锁问题主要还是由线程的并发执行导致的,解决这个问题需要结合具体的环境和需求进行,例如使用锁的公平锁,或者设置锁的超时时间等。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部