塌鼻子巴巴鲁 2018-05-24 12:52 采纳率: 45.5%
浏览 584
已采纳

关于Java死锁原理,苦想好久都不明白,希望大佬们帮忙!谢谢!

下面是一个Java的死锁模拟程序

package demo;

public class DeadLockDemo {

     public static void main(String[] args) {
         DeadLock dead = new DeadLock();
         Thread t0 = new Thread(dead);
         Thread t1 = new Thread(dead);
         t0.start();
         t1.start();
       }
}
package demo;

public class DeadLock implements Runnable {
     private int i = 0;
     public void run(){
       while(true){
         if(i%2==0){
           //先进入A同步,再进入B同步
           synchronized(LockA.locka){
             System.out.println(Thread.currentThread().getName()+"   if...locka");
             synchronized(LockB.lockb){
               System.out.println(Thread.currentThread().getName()+"   if...lockb");
             }
           }
         }else{
           //先进入B同步,再进入A同步
           synchronized(LockB.lockb){
             System.out.println(Thread.currentThread().getName()+"   else...lockb");
             synchronized(LockA.locka){
               System.out.println(Thread.currentThread().getName()+"   else...locka");
             }
           }
         }
         i++;
       }
     }
}
package demo;

public class LockA {
     private LockA(){}

     public  static final LockA locka = new LockA();
}
package demo;

public class LockB {
     private LockB(){}

     public static final LockB lockb = new LockB();
}

运行某一次的输出结果为:
Thread-0 if...locka
Thread-0 if...lockb
Thread-1 if...locka
Thread-1 if...lockb
Thread-1 else...lockb
Thread-0 if...locka
我想问的是: 1.两个线程Thread-0和Thread-1在方法run中调用的i是不是同一个i?
2.如果是同一个i,那么结果中当输出Thread-1 else...lockb后i的值应该是奇数,还没执行后面的i++,此时线程Thread-0抢占资源运行,由于i为奇数,应该走else语句,输出else...lockb才对啊,为什么最后会输出Thread-0 if...locka?
并且,输出结果的前四个不应该都是if....才对啊?
3.如果不是同一个i,又为什么不是呢?调用同一个对象,i应该是同一个才对啊?

  • 写回答

2条回答 默认 最新

  • DengDengLei 2018-05-24 14:13
    关注

    是同一个i,有一种情况你忽略了:
    线程0第一次进入if(i%2==0)判断为true后,还未来得及执行后面的语句,然后此时线程1抢占资源,因为此时线程0还没来得及执行i++,因此对线程1而言i还是0。
    你可以添加更多输出语句查看线程的执行情况:
    1、在i%2==0的判断后面添加输出:if(i%2==0){System.out.println(Thread.currentThread().getName()+" here");...}
    2、在i++前添加输出:System.out.println(Thread.currentThread().getName()+" i++"); i++;

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥50 swiftui @query 报错
  • ¥50 怎么解决刷卡或扫码后,点击软件输入框,win10屏幕键盘不会自动弹出的问题
  • ¥15 如何使用arcgispro的训练深度模型,发现water和nowater精度为0?(相关搜索:深度学习)
  • ¥20 matlab作业不太懂呀有问题能给个代码吗
  • ¥15 自制电路图为何无法驱动ESP01S?
  • ¥15 前端加access数据库
  • ¥15 ARCGIS 多值提取到点 ERROR 999999
  • ¥15 mysql异常断电, [MY-011971] [InnoDB]
  • ¥15 uni.onBluetoothDeviceFound熄屏不运行
  • ¥15 求PHDA糖尿病并发症数据集,有偿