这是一个线程死锁

时间:2014-12-03 19:03:38

标签: java multithreading deadlock

我想故意做/测试java线程死锁状态,所以我做了以下示例代码:

public class TestDeadLock extends Thread{
    private Integer a=new Integer(9);
    public void run(){

        if(Thread.currentThread().getName().equals("t1")){
            XXXX();
        }
        else{
            ZZZZ();
        }
    }

    public void XXXX(){
        System.out.println("inside XXXX");
        synchronized(a){
            a++;
            ZZZZ();
        }
        System.out.println("xxxxxxxxxxxxxxxxxxx");
        //ZZZZ();
    }

    public synchronized void ZZZZ(){
        System.out.println("inside ZZZZ");
        synchronized(a){
            a--;
            XXXX();
        }
        System.out.println("zzzzzzzzzzzzzzzzzzzzz");
    }

    public static void main(String[] args) throws InterruptedException {
        TestDeadLock tdl=new TestDeadLock();
        Thread t1=new Thread(tdl);
        Thread t2=new Thread(tdl);
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();

        Thread.sleep(1000);
        System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="+tdl.a);
    }
}

输出结果如下:

在XXXX内

在ZZZZ内

= - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = 10

输出未退出。

我想知道,是因为线程达到了Dead Lock状态?这是体验Dead Lock的正确范例。如果我错了,建议或纠正我。

4 个答案:

答案 0 :(得分:6)

不,你没有遇到死锁。您遇到了StackOverflowError,因为您遇到了无限循环。

请注意您的方法

public synchronized void ZZZZ() {
  System.out.println("inside ZZZZ");

    XXXX(); // run-time exception
}

相当于

public void ZZZZ() {
  synchronized(this) {
    System.out.println("inside ZZZZ");

      XXXX(); // run-time exception
  }
}

您没有导致死锁,因为您正在处理两个不同的实例。 线程1锁定t1,线程2锁定t2

答案 1 :(得分:3)

您的ZZZZ()方法包含对XXXX()方法的调用,反之亦然。 因此,您创建了一个永无止境的调用链:ZZZZ() - > XXXX() - > ZZZZ() - > XXXX() - >等

最终,您的堆栈将从推入堆栈的所有嵌套方法调用中变得过大。因此,您将获得例外。

答案 2 :(得分:0)

试试这个例子:

public class TestThread {
   public static Object Lock1 = new Object();
   public static Object Lock2 = new Object();

   public static void main(String args[]) {

      ThreadDemo1 T1 = new ThreadDemo1();
      ThreadDemo2 T2 = new ThreadDemo2();
      T1.start();
      T2.start();
   }

   private static class ThreadDemo1 extends Thread {
      public void run() {
         synchronized (Lock1) {
            System.out.println("Thread 1: Holding lock 1...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 1: Waiting for lock 2...");
            synchronized (Lock2) {
               System.out.println("Thread 1: Holding lock 1 & 2...");
            }
         }
      }
   }
   private static class ThreadDemo2 extends Thread {
      public void run() {
         synchronized (Lock2) {
            System.out.println("Thread 2: Holding lock 2...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 2: Waiting for lock 1...");
            synchronized (Lock1) {
               System.out.println("Thread 2: Holding lock 1 & 2...");
            }
         }
      }
   } 
}

这准确地显示了线程到达死锁。

以下是解决方案:

public class TestThread {
   public static Object Lock1 = new Object();
   public static Object Lock2 = new Object();

   public static void main(String args[]) {

      ThreadDemo1 T1 = new ThreadDemo1();
      ThreadDemo2 T2 = new ThreadDemo2();
      T1.start();
      T2.start();
   }

   private static class ThreadDemo1 extends Thread {
      public void run() {
         synchronized (Lock1) {
            System.out.println("Thread 1: Holding lock 1...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 1: Waiting for lock 2...");
            synchronized (Lock2) {
               System.out.println("Thread 1: Holding lock 1 & 2...");
            }
         }
      }
   }
   private static class ThreadDemo2 extends Thread {
      public void run() {
         synchronized (Lock1) {
            System.out.println("Thread 2: Holding lock 1...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 2: Waiting for lock 2...");
            synchronized (Lock2) {
               System.out.println("Thread 2: Holding lock 1 & 2...");
            }
         }
      }
   } 
}

来源:http://www.tutorialspoint.com/java/java_thread_deadlock.htm

答案 3 :(得分:-1)

Jase Pellerin给出的例子是死锁的一个很好的例子但它有一个错误(抱歉Jase Pellerin,我相信你是无意中做到的)。在这里,两种方法都试图首先获得Lock1然后Lock2。我认为应该是其他方式。

Thread1{

synchronized (Lock1) {

synchronized (Lock2) {}

}
}

Thread2{

 synchronized (Lock2) {

 synchronized (Lock1) {}

 }
 }