簡體   English   中英

Java中的多線程死鎖

[英]Multithreading Deadlock in Java

請,有人可以解釋一下為什么這段代碼是僵局。 似乎應該可以正常工作。 請詳細說明。 謝謝。

public class H extends Thread {
    String info = "";
    public H (String info) {
        this.info = info;
    }

    public synchronized void run() {
        try {
            while (true) {
                System.out.println(info);
                notify();
                wait();
            }
        } catch (Exception e) {}

    }
    public static void main(String[] args) {
          new H("0").start();
          new H("1").start();
    }

}

每個線程都this進行synchronized (通過方法上的synchronized關鍵字),這對於兩個線程對象中的每個對象都是不同的。 他們每個人都打電話notifywait但他們不進行交互,因為this是不同的。 因此,在第一次迭代中,它們都調用wait並永遠阻塞,因為沒有人可以喚醒它們。

這是我為使代碼按預期工作而進行的一些更改。 請注意允許線程進行通信的共享靜態字段:

public class Test extends Thread {
    String info = "";
    static final Object signal = new Object();
    static volatile String current = null;

    public Test (String info) {
        this.info = info;
    }

    public void run() {
        try {
            synchronized(signal) {
                while (true) {                                  
                    while(current.equals(info))
                        signal.wait();
                    System.out.println(info);
                    current = info;
                    signal.notify();
                }
            }
        } catch (Exception e) {}

    }

    public static void main(String[] args) {
        Test.current = "0";
        new Test("0").start();
        new Test("1").start();
    }
}

我想在您的原始代碼上做一些其他說明:

  • 您應該嘗試實現Runnable而不是擴展Thread 這樣可以為您提供更大的靈活性。
  • 不要吞下例外。

notifywait在不同的Thread對象上調用,因此當一個線程進入wait ,另一個線程將不會通知它,而是由每個線程通知自己。

流量非常大(可能會有交錯):

  1. ThreadA開始
  2. ThreadA通知正在等待ThreadA鎖的對象
  3. ThreadA等待ThreadA的鎖
  4. 線程B啟動
  5. ThreadB通知正在等待ThreadB鎖的對象
  6. ThreadB等待ThreadB的鎖

最終狀態-兩個線程都在等待,沒有人通知它們。

notify()僅喚醒當前正在等待對象的線程。 當您調用notify()時,在任何情況下都沒有線程在等待。 然后,當您調用wait時,您永遠不會有任何通知()的代碼。 基本上,您不能從同一線程通知線程,因為它必須處於等待狀態。 等待一段時間后,嘗試從主線程通知它們,看看會發生什么。

public class H extends Thread {
    String info = "";
    public H (String info) {
        this.info = info;
    }

    public synchronized void run() {
        try {
            while (true) {
                System.out.println(info);
                wait();
            }
        } catch (Exception e) {}

    }
    public static void main(String[] args) throws Exception {
          H a = new H("0").start();
          H b = new H("1").start();
          Thread.sleep(1000);
          a.notify();
          b.notify();
    }
}

請注意,兩個線程都不會通知另一個線程。 在一個對象上等待僅在其上等待,而不是整個類。

TL; DR:notify()沒有執行任何操作,而wait()創建了死鎖。

暫無
暫無

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

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