You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高并发多线程Java应用登录环节死锁问题排查求助

reload4j v1.2.24高并发场景下的死锁判定

问题场景

高并发多线程Java应用的登录环节出现线程阻塞,Thread-5线程卡住,使用日志库为reload4j v1.2.24,需判断是否存在死锁。

日志配置

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="default" class="org.apache.log4j.AsyncAppender"> </appender>
</log4j:configuration>

线程栈分析

AsyncAppender-Dispatcher-Thread-0(调度线程)

"AsyncAppender-Dispatcher-Thread-0" #21 daemon prio=5 os_prio=0 tid=0x00007f13d2338000 nid=0x2454d waiting for monitor entry [0x00007f13a171a000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at org.apache.log4j.Category.callAppenders(Category.java:192)
        - waiting to lock <0x00000006c006e230> (a org.apache.log4j.spi.RootLogger)
        at org.apache.log4j.Category.forcedLog(Category.java:364)
        at org.apache.log4j.Category.log(Category.java:771)
        at org.slf4j.impl.Log4jLoggerAdapter.log(Log4jLoggerAdapter.java:581)
        at org.apache.commons.logging.impl.SLF4JLocationAwareLog.error(SLF4JLocationAwareLog.java:220)

该线程处于BLOCKED状态,正在等待获取RootLogger对象(<0x00000006c006e230>)的监视器锁,当前卡在Category.callAppenders方法中。

Thread-5(业务线程)

"Thread-5" #170 prio=5 os_prio=0 tid=0x00007f13b85d1000 nid=0x2680f in Object.wait() [0x00007f1396c20000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:502)
        at org.apache.log4j.AsyncAppender.append(AsyncAppender.java:190)
        - locked <0x00000006c0026878> (a java.util.ArrayList)
        at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:228)
        - locked <0x00000006c007e980> (a org.apache.log4j.AsyncAppender)
        at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:56)
        at org.apache.log4j.Category.callAppenders(Category.java:194)
        - locked <0x00000006c006e230> (a org.apache.log4j.spi.RootLogger)
        at org.apache.log4j.Category.forcedLog(Category.java:364)
        at org.apache.log4j.Category.log(Category.java:771)
        at org.slf4j.impl.Log4jLoggerAdapter.log(Log4jLoggerAdapter.java:581)
        at org.apache.commons.logging.impl.SLF4JLocationAwareLog.info(SLF4JLocationAwareLog.java:164)

该线程处于WAITING状态,在AsyncAppender.append方法中调用Object.wait()等待队列空间。关键是它已经持有了调度线程需要的RootLogger对象锁,同时还持有AsyncAppender和队列ArrayList的锁,但因队列满进入等待,且未释放RootLogger锁。

结论

这是典型的死锁场景:

  • Thread-5持有RootLogger锁,等待调度线程处理日志队列以唤醒自己;
  • 调度线程需要RootLogger锁才能继续执行日志输出逻辑,但该锁被Thread-5持有,无法推进;
  • 双方陷入循环等待,且无线程能主动释放锁,形成死锁。

本质是reload4j的AsyncAppender设计缺陷:调度线程在处理日志时可能触发新的日志输出,而业务线程在写入异步日志时持有日志根节点锁,导致循环等待。

内容的提问来源于stack exchange,提问作者user24857774

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 19:20:07