synchronized死锁问题

wqdsb 2017-03-04 10:44:18
public class DieLockDemo implements Runnable {
public Object o1 = new Object();
public Object o2 = new Object();

@Override
public void run() {
String s = Thread.currentThread().getName();
if (s.equals("A")) {
synchronized (o2) {
// o2 = new String("ddd");
synchronized (o1) {
System.out.println("o1");
}
}
} else {
synchronized (o1) {
System.out.println("o1");
synchronized (o2) {
System.out.println("o2");
}
}
}
}
public static void main(String[] args) {
DieLockDemo d = new DieLockDemo();
Thread t1 = new Thread(d,"A");
Thread t2 = new Thread(d);
t1.start();
t2.start();

}
}

为什么那行被注释了还可以经常发生死锁,但是删除掉注释后死锁一次都没发生?
是不是实验次数太少了?新赋值应该不会破坏锁对象吧?
...全文
230 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
wqdsb 2017-03-08
  • 打赏
  • 举报
回复
引用 1 楼 wwwrrrmmm 的回复:
我来解释一下。 就用你上面这一段来跑,时不时就死锁。 分两种情况,如果两个线程,t1先跑,print o1,那没问题,不会锁。 如果是t2先跑,那就很大机会死锁。 根据t2的代码,先拿o1锁,再print o1,再拿o2锁(这时候拿到锁的机会特别小)因为t1 的代码,一上来就先拿了o2锁。 所以,很大的概率,t1拿着o2,在等o1,t2拿着o1,在等o2,所以就死锁了。 当然也有小概率,成功打出 o1 o2 o1 (试验过了) =============================== o2 = new String("ddd"); 至于你说给o2 new String....一般操作多线程都不会去动lockObj的。 你想一下内存里有一个obj(名字是o2), 被线程t1拿着,你这时候重新new一个obj出来(名字是o2)。给另一个线程t2用,那内存里就有两个obj了。这样做没有意义。
谢谢!
wwwrrrmmm 2017-03-06
  • 打赏
  • 举报
回复
补充一句方便理解。 下面这个o1是100%会被print出来的。 } else { synchronized (o1) { System.out.println("o1");
wwwrrrmmm 2017-03-06
  • 打赏
  • 举报
回复
我来解释一下。 就用你上面这一段来跑,时不时就死锁。 分两种情况,如果两个线程,t1先跑,print o1,那没问题,不会锁。 如果是t2先跑,那就很大机会死锁。 根据t2的代码,先拿o1锁,再print o1,再拿o2锁(这时候拿到锁的机会特别小)因为t1 的代码,一上来就先拿了o2锁。 所以,很大的概率,t1拿着o2,在等o1,t2拿着o1,在等o2,所以就死锁了。 当然也有小概率,成功打出 o1 o2 o1 (试验过了) =============================== o2 = new String("ddd"); 至于你说给o2 new String....一般操作多线程都不会去动lockObj的。 你想一下内存里有一个obj(名字是o2), 被线程t1拿着,你这时候重新new一个obj出来(名字是o2)。给另一个线程t2用,那内存里就有两个obj了。这样做没有意义。

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧