这个死锁的原因:一个动作需要两个临界对象。
静态同步方法,就是一个临界对象。
这种场景,静态同步方法每次只能有一个线程持有。
如果存在另一个临界对象,静态同步方法中也需要获取这个临界对象。即一个动作需要两个临界对象。

We are experiencing deadlocks on our server.

We have tested with log4j version 1.2.8 up to and including 1.2.15

We have identified that cause to be a log statement inside a
synchronized block,
which is called from different threads. We have attached to very simplified classes, to reproduce the deadlock.
Our framework is a lot more complex, where log4j can be called
indirectly with reflection, not neccessarily by us, but from third party
libraries etc. The deadlock can be reproduced always. Is our usage (or library usage) of log4j faulty, or is it a bug?
import org.apache.log4j.Logger;

public class FindDeadLock {

    public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
Logger.getLogger(getClass()).info(new FindDeadLock());
}
}).start();
DeadLockingObject.getInstance();//lineNO:13
} public String toString() {
/* now we are inside log4j, try to create a DeadLockingObject */
DeadLockingObject.getInstance();
return "Created DeadlockObject, returning string";
}
}
import org.apache.log4j.Logger;

public final class DeadLockingObject {
private static final Logger LOG = Logger.getLogger(DeadLockingObject.class
.getName());
private static DeadLockingObject singleton = new DeadLockingObject(); private DeadLockingObject() {
} public synchronized static DeadLockingObject getInstance() {
try {
// to make the deadlock occur
Thread.sleep(100);
} catch (InterruptedException e) {
LOG.error(e);
}
LOG.info("Returning nice singleton");//lineNO:20
return singleton;
}
}

Here is our log4j configuration:

# Set root logger level to DEBUG and its only appender to A1. 
log4j.rootLogger=INFO, A1

# A1 is set to be a ConsoleAppender. 
log4j.appender.A1=org.apache.log4j.ConsoleAppender

# A1 uses PatternLayout. 
log4j.appender.A1.layout=org.apache.log4j.PatternLayout 
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

Analyse:

"main" - Thread t@1
java.lang.Thread.State: BLOCKED
at org.apache.log4j.Category.callAppenders(Category.java:205)
- waiting to lock <341960> (a org.apache.log4j.spi.RootLogger) owned by "Thread-0" t@8
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.info(Category.java:666)
at loggerlock.DeadLockingObject.getInstance(DeadLockingObject.java:20)
- locked <105738> (a java.lang.Class)
at loggerlock.FindDeadLock.main(FindDeadLock.java:13) Locked ownable synchronizers:
- None

main线程:

(1)DeadLockingObject.getInstance();//获取DeadLockingObject class级别的锁
(2)LOG.info("Returning nice singleton");//打印日志需要依次获取class org.apache.log4j.spi.RootLogger、org.apache.log4j.ConsoleAppender的锁

"Thread-0" - Thread t@8
java.lang.Thread.State: BLOCKED
at loggerlock.DeadLockingObject.getInstance(DeadLockingObject.java:16)
- waiting to lock <105738> (a java.lang.Class) owned by "main" t@1
at loggerlock.FindDeadLock.toString(FindDeadLock.java:18)
at org.apache.log4j.or.DefaultRenderer.doRender(DefaultRenderer.java:37)
at org.apache.log4j.or.RendererMap.findAndRender(RendererMap.java:80)
at org.apache.log4j.spi.LoggingEvent.getRenderedMessage(LoggingEvent.java:368)
at org.apache.log4j.helpers.PatternParser$BasicPatternConverter.convert(PatternParser.java:402)
at org.apache.log4j.helpers.PatternConverter.format(PatternConverter.java:65)
at org.apache.log4j.PatternLayout.format(PatternLayout.java:506)
at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:310)
at org.apache.log4j.WriterAppender.append(WriterAppender.java:162)
at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
- locked <81aa7a> (a org.apache.log4j.ConsoleAppender)
at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)
at org.apache.log4j.Category.callAppenders(Category.java:206)
- locked <341960> (a org.apache.log4j.spi.RootLogger)
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.info(Category.java:666)
at loggerlock.FindDeadLock$1.run(FindDeadLock.java:10)
at java.lang.Thread.run(Unknown Source) Locked ownable synchronizers:
- None

Thread-0线程:
(1)Logger.getLogger(getClass()).info(。。。//
//获取Class org.apache.log4j.spi.RootLogger的锁
//获取Class org.apache.log4j.ConsoleAppender的锁
(3)new FindDeadLock()的toString方法中

DeadLockingObject.getInstance();//需要获取Class DeadLockingObject锁
http://apache-logging.6191.n7.nabble.com/Log4j-1-2-x-deadlock-bug-or-faulty-usage-td7658.html

Tips:
(1)线程状态 waiting for monitor entry 表示目前线程正在等待去锁住一个对象(其它线程可能正拥有该对象锁)。该现象会发生在当多线程同时去执行同步代码块或方法时。注意锁是对对象而言的,而不是单个的方法,也就是说当一个线程去执行某个对象的同步方法时,它须先锁住那个对象。
(2)

要找出所有Thread栈信息,并且分类排序,比如:

因为log4j等待Logger的而阻塞的有多少条线程,这种:
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.log4j.Category.callAppenders(Category.java:204)
- waiting to lock <0x00002aab2f555948> (a org.apache.log4j.spi.RootLogger)

因为JDBC操作等待数据库返回的有多少条线程,这种:
ava.lang.Thread.State: BLOCKED (on object monitor)
at oracle.jdbc.driver.T4CMAREngine.unmarshalDALC(T4CMAREngine.java:2347)
at oracle.jdbc.driver.T4C8TTIuds.unmarshal(T4C8TTIuds.java:134)
at oracle.jdbc.driver.T4CTTIdcb.receiveCommon(T4CTTIdcb.java:155)

然后根据数量规模排序,来判断瓶颈可能发生的位置。
http://bbs.csdn.net/topics/390033107?page=1#post-398824236

												

一个与Log4j相关的死锁(转)的更多相关文章

  1. 一个SQL Server 2008 R2 死锁的问题解决

    问题场景:在客户那碰到一个操作卡死的现象 问题解决: 1.如何挂钩是死锁问题:通过代码跟踪,发现是指执行一个SQL语句超时,因此猜想可能是表锁住了 2.如果确认是思索问题:通过SQL发现死锁,以下是相 ...

  2. Log4j 相关

    Log4j(Log for Java) Log4j是Apache提供的一种专门用于Java程序记录日志的工具,是目前主流的开发日志技术. 日志的作用: 1.记录系统运行过程中的重要运行信息 a) 付费 ...

  3. 记一个openwrt reboot异步信号处理死锁问题

    写在前面 觉得本页面排版单调的话,可以尝试到这里看. 问题背景 在 openwrt 上碰到了一个偶现的 reboot 失效问题.执行 reboot 之后系统并没有重启,此时控制台还能工作. 初步排查 ...

  4. 记一个界面刷新相关的Bug

    今天遇到一个比较有意思的bug, 这里简单记录下. Bug的症状是通过拖拉边框把我们客户端主窗口拖小之后,再最大化,会发现窗口显示有问题, 看起来像是刷新问题, 有些地方显示的不对了. 这里要说明的是 ...

  5. 汇编入门——使用DOSBox写一个HelloWorld以及相关软件安装

    0.0.0) 在D盘建立一个ASM文件夹 0.0.1) 放入所需要的文件 1所标示的红色框为必须要存在的文件,要处理汇编文件.百度网盘中下载. 2自己编写的汇编(asm)文件. 3编译汇编自己生成的文 ...

  6. log4j相关配置

    1.概述         log4j是Apache提供的一个日志实现,可以用于我们项目中的日志记录,有log4j1和log4j2两个版本,本文使用log4j2这个版本.SLF4J(Simple log ...

  7. 分享一个 UiPath Studio 相关的公众号

    RPA 和 UiPath 方面的资料比较少,因此我们自己创建了一个公众号,专门用于传播 UiPath 相关的知识. 会定期发布 UiPath 学习相关的信息.是目前难得的 UiPath 中文资源. 公 ...

  8. 【solr基础教程之中的一个】Solr相关知识点串讲

           Solr是Apache Lucene的一个子项目.Lucene为全文搜索功能提供了完备的API.但它仅仅作为一个API库存在.而不能直接用于搜索. 因此,Solr基于Lucene构建了一 ...

  9. 一个double free相关问题的澄清

    引言 前一阵定位 Oracle 的 OCI 接口相关的一个内存释放问题,在网上看到了链接如下的这篇文章: 一个C++bug引入的许多知识 看到后面说 vector 里的两个单元里的内部成员指针地址是一 ...

随机推荐

  1. PHP学习笔记6-时间/日期

    时区/时间/日期 输出unix时间戳(从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数),用time() echo time();//unix时间戳 输出结果:143557475 ...

  2. iOS XMPP之常见错误一:(<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>)

    在XMPP开发中,使用XMPPStream进行连接服务器后,验证过程中,比较常见的一个错误是 <failure xmlns="urn:ietf:params:xml:ns:xmpp-s ...

  3. Ajax辅助方法

    目前为止,我们已经考察了如何编写客户端JavaScript代码,以发送并接受服务器的数据.然而,在使用ASP.NET MVC时,还有另一种方法可用来执行Ajax调用,这就是Ajax辅助方法. Ajax ...

  4. 使用Android studio下载github上的工程及问题解决

    Android studio内置了github的插件,可以直接下载github上的工程,感觉好爽啊.具体怎么做呢?1.如图所示操作,如果是初次使用会提示输入用户名密码. 2.等android stud ...

  5. 《HTML 5网页开发实例具体解释》文件夹

    第一篇  从宏观上认识HTML 5 讲述了HTML 5引发的Web革命.HTML 5的总体特性.HTML 5相关概念和框架和开发环境搭建. 第1章 HTML 5引发的Web革命 1.1  你是不是真的 ...

  6. block 解析 - 静态变量

    静态变量 上一篇 我们了解了block全局变量的使用,静态变量和全局变量一样,可以直接在block内部使用,也可以在block内部修改 引用官方文档: Global variables are acc ...

  7. 道可叨 | Python 标准库 urllib2 的使用细节

    道可叨 | Python 标准库 urllib2 的使用细节 request = urllib2.Request(uri) request.add_header('User-Agent', 'fake ...

  8. 搭建Windows SVN服务器及TortoiseSVN使用帮助和下载

    搭建Windows SVN服务器: 用的SVN服务器通常为外部,例如Google Code的服务器,不过,做为一个程序开发人员,就算自己一个人写程序,也应该有一个SVN版本控制系统,以便对开发代码进行 ...

  9. perl 处理perl返回的json

    [root@wx03 ~]# cat a14.pl use Net::SMTP; use LWP::UserAgent; use HTTP::Cookies; use HTTP::Headers; u ...

  10. VC 无标题栏对话框移动

    操作系统:Windows 7软件环境:Visual C++ 2008 SP1本次目的:实现无框移动 所谓的无标题栏对话框,是基于对话框的工程,对话框属性Border设置为None,对话框如下所示: 为 ...