Java的死锁分析

在编写并发程序的时候,死锁问题不得不面对,注意,消除。

 

何为死锁

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值