在编写并发程序的时候,死锁问题不得不面对,注意,消除。
何为死锁
wiki的解释是这样的:“这里指的是进程
死锁,是一个计算机技术的名词。它是操作系统
或软件运行的一种状态:在多工系统下,当一个或多个进程等待系统资源,而系统资源又同时被此进程本身或者其 它进程占用,就形成了死锁。”
例如,线程1锁住了资源A,并试图去访问资源B,而此时线程2锁住了资源B,并试图访问资源A,这样线程1和2均锁住了对方需要的资源,并且都在等
待对方持有的资源释放后才能继续运行释放自己持有的资源,死锁发生了,两个线程都因为等待资源被阻塞,假如没有一种手段来解除这种互相等待,可以想象,在
理论上二者都会永远等待下去。
这种现象可以这样说明:
Thread 1 locks A,waits for B
Thread 2 locks B,wats for A
下面我们展示一段java代码:
public class TreeNode {
TreeNode parent = null;
List children = new ArrayList();
public synchronized void addChild(TreeNode child) {
if (!this.children.contains(child)) {
this.children.add(child);
child.setParentOnly(this);
}
}
public synchronized void addChildOnly(TreeNode child) {
if (!this.children.contains(child)) {
this.children.add(child);
}
}
public synchronized void setParent(TreeNode parent) {
this.parent = parent;
parent.addChildOnly(this);
}
public synchronized void setParentOnly(TreeNode parent) {
this.parent = parent;
}
}
假如有两个TreeNode实例:child,parent。如果线程(1)调用parent.addChild(child),同时,线程(2)
调用child.setParent(parent)。对线程(1)来说,他锁住了parent对象,而线程(2)同时锁住了child对象。在这个时
候,线程(1)试图去请求child,要获得child对象的锁,但是由于这把锁已经被线程(2)持有,线程(1)不得不阻塞等待,当线程(2)执行到
parent.addChildOnly(this)时,他要获得parent的锁,很不幸的是,这把锁已经被parent占据了,他也不得不阻塞等待。
就这样,杯具发生了,线程(1)和线程(2)都将阻塞等待下去。
更复杂的死锁现象
Thead 1 locks A,waits for B,
Thead 2 locks B,waits for C,
Thead 3 locks C,waits for D,
Thead 4 locks D,waits for A
数据库的死锁
一个事务已经锁定了一条记录(a)进行修改,现在,他需要修改记录(b),当他去请求记录(b)的锁时,很不幸,记录(b)被另外一个事务锁住,更碰巧的是,持有记录(b)的锁的事务已经在这个时候刚好要去请求记录(a)的锁,死锁再次发生。下面的现象可以说明:
Transaction 1 request 1,locks record 1 for update
Transaction 2 request 1,locks record 2 for update
Transaction 1 request 2,locks record 2 for update
Transaction 2 request 2,locks record 1 for update
分享到:
相关推荐
Java死锁的问题分析与研究
我们提出了一种针对参与者模型的通信死锁分析的独特方法,该方法的分析结果偏低。 我们的分析通过在称为从属依赖关系图的新型依赖关系图中找到循环依赖关系来检测狭窄定义的通信死锁。 从属依赖关系图基于Actor之间...
这个对于定位死锁很重要,很简单。在运行java控制台的时候,都会用 java -classpath XXX org.XXX. main 这种方法 在管理控制台中按下ctrl + break 就能从界面上获得及时的堆栈信息了,但是这些信息很不方便。那么又...
尽管出现了一些静态分析库可以帮助我们发现可能出现的死锁,我们还是有必要在运行时检测到死锁,并且得到有用的信息,以便我们解决这个问题或者重启程序,或者做些其他的事情。 在编程中使用ThreadMXBean类来检测...
主要介绍了Java中死锁的原理,结合具体案例形式分析了java死锁形成的相关原理,需要的朋友可以参考下
煤矿监控系统组态软件客观上要求...论文分析了煤矿组态软件体系结构,论述了该软件多线程死锁的原因,研究了具有优先级的多线程排队机制和调度机制,并利用Java语言编程实现,解决了矿用组态软件的死锁问题,达到预期目的。
主要介绍了Java多线程死锁,结合实例形式分析了Java多线程出现死锁的相关原因与操作注意事项,需要的朋友可以参考下
性能测试,线程的 dump 看到线程的 死锁,等待 运行状态
死锁是两个甚至多个线程被永久阻塞时的一种运行局面,这种局面的生成伴随着至少两个线程和两个或者多个资源。在这里我已写好一个简单的程序,它将会引起死锁方案然后我们就会明白如何分析它
主要介绍了Java模拟死锁发生之演绎哲学家进餐问题,结合具体演绎哲学家进餐问题的案例形式详细分析了死锁机制与原理,需要的朋友可以参考下
IBM Thread and Monitor Dump Analyzer for Java(简称 jca)。它可以识别Java线程中的挂起,死锁,资源竞争,和瓶颈。 使用方法: java -Xmx1000m -jar jca456.jar
近似过程分析包含以下内容的实现,文档和输出:整个JRE的近似和过程静态分析,以预测死锁利用。 赞成:因为它减少了“同步”语句块,而过程:因为它减少了Java的动态分派功能。 ProceduralAnalysis包含以下各项的...
jca工具分析死锁及内存情况
该工具用来排查线上程序出现内存泄漏或溢出,死锁等相关问题,快速分析堆栈异常情况,找到问题代码进行修复。
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...
Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来...
IBM最新的线程分析工具,可以分析线程的总体情况、线程锁的情况、线程是否死锁的情况。含readme。
怎么避免死锁等问题展开分析,通过大量的代码和案例演示向大家描述死锁的前世今生。 快速到达看这里死锁是什么,有什么危害?写一个死锁的例子案例一:必然发生死锁案例二:两个账户转账案例三:多人多次转账发生...