dead lock 试验

package com.asc.mmmu;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

class Cell { // Do not use

private static final Log log=LogFactory.getLog(Cell.class);
private long value;
synchronized long getValue() { return
value; }
synchronized void setValue(long v) {
value = v; }
synchronized void swapValue(Cell other)
{
long t = getValue();
long v = other.getValue();
setValue(v);
other.setValue(t);
}


static class R implements Runnable{

Cell a;
Cell b;
@Override
public void run() {

a=new Cell();
a.setValue(1);
b=new Cell();
b.setValue(2);

for(int i=0;i<100;i++){


try {
log.info("a swap b");
Thread.sleep(10);
} catch (InterruptedException e) {
log.error("sleep erro",e);
}

a.swapValue(b);


try {
log.info("b swap a");
Thread.sleep(10);
} catch (InterruptedException e) {
log.error("sleep erro",e);
}



b.swapValue(a);

}
}





}

public static void deadlock(){

Cell.R r=new Cell.R();

Thread[] a=new Thread[2];


for (int i = 0; i < 2; i++) {

a[i]=new Thread(r);
a[i].start();
}
try {
a[0].join();
} catch (InterruptedException e) {
log.error("sleep error",e);
}
}

public static final void main(String[] args){

log.info("begin");

Cell.deadlock();


log.info("end");

}


}

试验表明: 关键是
1.synchronized void swapValue(Cell other){} 的 synchronized .
2.a.swapValue(b);b.swapValue(a);

这两个条件,同时具备,才会deadlock.


解决:resource ordering

public void swapValue(Cell other) {
if (other == this) // alias check
return;
else if (System.identityHashCode(this) < System.identityHashCode(other))
this.doSwapValue(other);
else
other.doSwapValue(this);
}

protected synchronized void doSwapValue(Cell other) {
// same as original public version:
long t = getValue();
long v = other.getValue();
setValue(v);
other.setValue(t);
}

关键:System.identityHashCode(this) < System.identityHashCode(other)) ,不再deadlock.

另外一个办法:外部lock
class ExternalLock {
public static synchronized void swapCells(Cell cell1, Cell cell2) {
cell1.swapValue(cell2);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值