簡體   English   中英

該代碼適用於notifyAll,但不適用於notify

[英]The code works with notifyAll, but doesn't with notify

我正在嘗試用兩個線程創建一個簡單的“ Ping-Pong”程序(Pong線程僅在Ping線程之后打印其消息)。

問題是,為什么以下代碼始終卡住,但是對notifyAll正常工作?

這是我的代碼:

public class Main {
private static class Ping extends Thread {
    private int rounds;
    Ping(int rounds) { this.rounds = rounds; }
    @Override
    public void run() {
        try {
            synchronized(this) {
                while(rounds > 0) {
                    System.out.println("Ping");
                    notify();
                    wait();
                    --rounds;
                }
                notify();
            }
            System.out.println("Ping done");
        } catch(Exception ignored) { ignored.printStackTrace(); }
    }

    public boolean isDone() { return rounds <= 0; }
}

private static class Pong extends Thread {
    private final Ping ping;
    Pong(Ping ping) { this.ping = ping; }
    @Override
    public void run() {
        try {
            synchronized(ping) {
                while(!ping.isDone()) {
                    System.out.println("Pong");
                    ping.notify();
                    ping.wait();
                }
            }
            System.out.println("Pong done");
        } catch(Exception ignored) { ignored.printStackTrace(); }
    }
}

public static void main(String[] args) throws Exception {
    Ping ping = new Ping(15);
    Pong pong = new Pong(ping);

    ping.start();
    pong.start();

    ping.join();
    pong.join();
}
}

從代碼中刪除ping.join,它將起作用。 ping.join使主線程在ping實例上等待,因此您有2個線程在ping上等待。 這就是為什么它僅適用於notifyAll的原因。

實際上不需要聯接,Java仍將等待Ping和Pong終止

如果您使用單獨的鎖進行同步,則不會出現此類問題。 在線程(Ping是線程)上同步是一個壞主意

線程協調是不可靠的,它取決於線程調度程序。 這個

notify();
wait();

可能是個問題。 假設您發送notify(),而當當前線程移至wait()時,另一個線程喚醒了它的工作並發送notify(),如果當前線程尚未到達wait(),則通知將丟失。 您可以輕松地模擬這種情況以查看它是正確的。

暫無
暫無

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

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