塌鼻子巴巴鲁 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条)

报告相同问题?

悬赏问题

  • ¥30 matlab ode45 未发现警告,但是运行出错
  • ¥15 vscode platformio
  • ¥15 代写uni代码,app唤醒
  • ¥15 全志t113i启动qt应用程序提示internal error
  • ¥15 ensp可以看看嘛.
  • ¥80 51单片机C语言代码解决单片机为AT89C52是清翔单片机
  • ¥60 优博讯DT50高通安卓11系统刷完机自动进去fastboot模式
  • ¥15 minist数字识别
  • ¥15 在安装gym库的pygame时遇到问题,不知道如何解决
  • ¥20 uniapp中的webview 使用的是本地的vue页面,在模拟器上显示无法打开