一个与Log4j相关的死锁(转)
这个死锁的原因:一个动作需要两个临界对象。
静态同步方法,就是一个临界对象。
这种场景,静态同步方法每次只能有一个线程持有。
如果存在另一个临界对象,静态同步方法中也需要获取这个临界对象。即一个动作需要两个临界对象。
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相关的死锁(转)的更多相关文章
- 一个SQL Server 2008 R2 死锁的问题解决
问题场景:在客户那碰到一个操作卡死的现象 问题解决: 1.如何挂钩是死锁问题:通过代码跟踪,发现是指执行一个SQL语句超时,因此猜想可能是表锁住了 2.如果确认是思索问题:通过SQL发现死锁,以下是相 ...
- Log4j 相关
Log4j(Log for Java) Log4j是Apache提供的一种专门用于Java程序记录日志的工具,是目前主流的开发日志技术. 日志的作用: 1.记录系统运行过程中的重要运行信息 a) 付费 ...
- 记一个openwrt reboot异步信号处理死锁问题
写在前面 觉得本页面排版单调的话,可以尝试到这里看. 问题背景 在 openwrt 上碰到了一个偶现的 reboot 失效问题.执行 reboot 之后系统并没有重启,此时控制台还能工作. 初步排查 ...
- 记一个界面刷新相关的Bug
今天遇到一个比较有意思的bug, 这里简单记录下. Bug的症状是通过拖拉边框把我们客户端主窗口拖小之后,再最大化,会发现窗口显示有问题, 看起来像是刷新问题, 有些地方显示的不对了. 这里要说明的是 ...
- 汇编入门——使用DOSBox写一个HelloWorld以及相关软件安装
0.0.0) 在D盘建立一个ASM文件夹 0.0.1) 放入所需要的文件 1所标示的红色框为必须要存在的文件,要处理汇编文件.百度网盘中下载. 2自己编写的汇编(asm)文件. 3编译汇编自己生成的文 ...
- log4j相关配置
1.概述 log4j是Apache提供的一个日志实现,可以用于我们项目中的日志记录,有log4j1和log4j2两个版本,本文使用log4j2这个版本.SLF4J(Simple log ...
- 分享一个 UiPath Studio 相关的公众号
RPA 和 UiPath 方面的资料比较少,因此我们自己创建了一个公众号,专门用于传播 UiPath 相关的知识. 会定期发布 UiPath 学习相关的信息.是目前难得的 UiPath 中文资源. 公 ...
- 【solr基础教程之中的一个】Solr相关知识点串讲
Solr是Apache Lucene的一个子项目.Lucene为全文搜索功能提供了完备的API.但它仅仅作为一个API库存在.而不能直接用于搜索. 因此,Solr基于Lucene构建了一 ...
- 一个double free相关问题的澄清
引言 前一阵定位 Oracle 的 OCI 接口相关的一个内存释放问题,在网上看到了链接如下的这篇文章: 一个C++bug引入的许多知识 看到后面说 vector 里的两个单元里的内部成员指针地址是一 ...
随机推荐
- PHP学习笔记1-常量,函数
常量:使用const(php5)声明,只能被赋值一次,php5以下版本使用define: <?php const THE_VALUE = 100;//PHP5中才有const echo THE_ ...
- a='1,2,3,4,5'如何转换为['1','2','3','4','5']
a='1,2,3,4,5'如何转换为['1','2','3','4','5'] b=a.split(',') split函数自动将分隔后的元素以逗号为分隔符存放到列表中 用处:有时需要用户输入多个数字 ...
- Java--对象内存布局
在HotSpot虚拟机中,对象在内存中的存储布局可以分为3块区域:对象头部.实例数据.对齐填充. 一.对象头部Header的布局 Mark Word Class 指针 在32位系统下,上面两部分各占4 ...
- Codeforces Round #254 (Div. 2) DZY Loves Chemistry【并查集基础】
一开始不知道题意是啥意思,迟放进去反应和后放进去反应有什么区别 对于第三组数据不是很懂,为啥312,132的组合是不行的 后来发现这是一道考察并查集的题目 QAQ 怒贴代码: #include < ...
- 【集训笔记】动态规划背包问题【HDOJ1421【HDOJ1058【HDOJ2546
http://acm.hdu.edu.cn/showproblem.php?pid=2546 http://acm.zju.edu.cn/onlinejudge/showContestProblem. ...
- C++标准库类型vector及迭代器iterator简介
Vector是C++标准库类型,称为容器,一个容器中的所有对象必须是同一种类型的.与数组相比,其最大的优点就是动态增长.Vector是一个类模板,并不是数据类型,而vector<int>和 ...
- Global文件(修正篇)
什么是Global文件 Global.asax文件俗称为一个类,继承于Httpapplication类.位于应用程序根目录下.也可称为应用程序文件. 概述: Global文件是可选的,一般在创建应用程 ...
- Arduino 入门程序示例之一个 LED(2015-06-11)
前言 答应了群主写一些示例程序,一直拖延拖延拖延唉.主要还是害怕在各大高手面前班门弄斧……(这也算是给拖延症找一个美好的理由吧),这几天终于下决心要写出来了,各位高手拍砖敬请轻拍啊. 示例程序 首先是 ...
- SGU 495. Kids and Prizes( 数学期望 )
题意: N个礼品箱, 每个礼品箱内的礼品只有第一个抽到的人能拿到. M个小孩每个人依次随机抽取一个, 求送出礼品数量的期望值. 1 ≤ N, M ≤ 100, 000 挺水的说..设f(x)表示前x ...
- 面试中的Singleton
引子 “请写一个Singleton.”面试官微笑着和我说. “这可真简单.”我心里想着,并在白板上写下了下面的Singleton实现: 1 class Singleton 2 { 3 public ...