簡體   English   中英

Java多線程死鎖

[英]java deadlock in multithreading

我正在嘗試學習Java多線程。 當陷入僵局時,我真的很難理解這些概念。 這是我自己了解死鎖的代碼。但是它編譯沒有錯誤。但是當我運行它時,它顯示了一個Nullpointer異常。這是錯誤

堆棧跟蹤:

Exception in thread "Thread-0" java.lang.NullPointerException
        at deadlockA.run(deadlock.java:70)
        at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-1" java.lang.NullPointerException
        at deadlockB.run(deadlock.java:91)
        at java.lang.Thread.run(Thread.java:745)

請幫助我清楚地了解錯誤。

碼:

import java.io.*;

class A {
    public synchronized void funcA(B b) {
        System.out.println("INSIDE FIRST OBJECTS MONITOR");

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        b.last();
    }

    public synchronized void last() {
        System.out.println("INSIDE A's LAST");
    }

}

class B {
    public synchronized void funcB(A a) {
        System.out.println("INSIDE SECOND OBJECT MONITOR");

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println(e);
        }

        a.last();
    }

    public synchronized void last() {
        System.out.println("INSIDE A's LAST");
    }

}

class deadlockA implements Runnable {
    Thread t;
    A a1;
    B b1;

    deadlockA(B b2) {
        b1 = b2;
        t = new Thread(this);
        t.start();
    }

    public void run() {
        a1.funcA(b1);
    }

}

class deadlockB implements Runnable {
    Thread t;
    A a2;
    B b3;

    deadlockB(A a3) {
        a2 = a3;
        t = new Thread(this);
        t.start();
    }

    public void run() {
        b3.funcB(a2);
    }

}

class deadlock {
    public static void main(String args[]) {

        A A1 = new A();
        B B1 = new B();

        deadlockA da = new deadlockA(B1);
        deadlockB db = new deadlockB(A1);

    }
}

deadlockA(B b2)構造函數中,您無需初始化a1類變量,而是在run()使用它。 deadlockB(A a3) b3相同。

對象a1b3永遠不會初始化,因此在對象上調用函數會產生NullPointerException 檢查以下更正的代碼:

class deadlockA implements Runnable
{
  Thread t;
  A a1;
  B b1;
   deadlockA(B b2)
   {
   a1 = new A(); //Create an object
   b1=b2;
   t=new Thread(this);
   t.start();
   }

   public void run()
   {
     a1.funcA(b1);
   }

}


class deadlockB implements Runnable
{
  Thread t;
  A a2;
  B b3;

   deadlockB(A a3)
   {
     b3 = new B(); // Create an object
     a2=a3;
     t=new Thread(this);
     t.start();
   }

   public void run()
   {
     b3.funcB(a2);
   }

}

如果您想真正看到一個死鎖情況,請考慮查看以下發布的代碼:

public class MyDeadlock {

    String str1 = "Java";
    String str2 = "CPP";

    Thread trd1 = new Thread("My Thread 1"){
        public void run(){
            while(true){
                synchronized(str1){
                    synchronized(str2){
                        System.out.println(str1 + str2);
                    }
                }
            }
        }
    };

    Thread trd2 = new Thread("My Thread 2"){
        public void run(){
            while(true){
                synchronized(str2){
                    synchronized(str1){
                        System.out.println(str2 + str1);
                    }
                }
            }
        }
    };

    public static void main(String a[]){
        MyDeadlock mdl = new MyDeadlock();
        mdl.trd1.start();
        mdl.trd2.start();
    }
}

您的deadlockA class不會初始化a1 這就是程序拋出NullPointerException的原因。 您已經在堆棧跟蹤中找到了它:

Exception in thread "Thread-0" java.lang.NullPointerException //what was thrown
at deadlockA.run(deadlockz.java:70) //where it was throw - method 'run' of class 'deadlockA', line 70 of a file where you have deadlockA defined.

有問題的課程,並附有評論:

class deadlockA implements Runnable
{
    Thread t;
    A a1; //not initialized.
    B b1;

    deadlockA(B b2)
    {
        b1=b2;
        t=new Thread(this);
        t.start();
    }

    public void run()
    {
        a1.funcA(b1); //a1 object is null.
    } 
}

變量a1和b3沒有在任何地方初始化,這會導致NullPointerException。 順便說一句,您發布的堆棧跟蹤與您發布的代碼無關。

下面的代碼將幫助您更好地了解死鎖情況。 有兩個對象,線程1獲取對象1的鎖,線程2獲取對象2的鎖,5秒鍾后,線程1嘗試獲取對象2的鎖,該對象由線程2持有,線程2試圖獲取對象1的鎖,該對象1被線程1持有,這里循環依賴項(死鎖)。 希望這可以幫助。

final Object object1 = new Object();

final Object object2 = new Object();

Thread thread1 = new Thread() {
    public void run() {
    synchronized (object1) {
        try {
        Thread.sleep(5 * 1000);
        synchronized (object2) {
            System.out.println("I am here");
        }
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
    }
    }
};

Thread thread2 = new Thread() {
    public void run() {
    synchronized (object2) {
        try {
        Thread.sleep(5 * 1000);
        synchronized (object1) {
            System.out.println("I am here");
        }
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
    }
    }
};

thread1.start();
thread2.start();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM