关于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个回答

是同一个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++;

qq_37621279
塌鼻子巴巴鲁 谢谢你的回答,我现在已经懂了
一年多之前 回复

是同一个i,但是你的i没有线程保护,输出Thread-1 else...lockb后i的值应该是奇数,

后面的i++和线程Thread-0抢到资源这两个谁先谁后都有可能

qq_37621279
塌鼻子巴巴鲁 谢谢你帮忙解答疑惑,现在我明白了。
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!