Wie lange wartet ein Thread nach der Ausführung von wait (), wenn er nicht von anderen Threads benachrichtigt wird?

Aug 16 2020

Im folgenden Beispiel sollte der Hauptthread ewig warten, da er nicht vom untergeordneten Thread benachrichtigt wird. Der Haupt-Thread wird jedoch ausgeführt und die Ausgabe des folgenden Beispiels lautet:

c
l
total: 19900

Warum wird der Haupt-Thread ausgeführt?

public class ThreadX extends Thread {
    static int total = 0;

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 200; i++) {
                total = total + i;
            }
            System.out.println("c");

        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadX t = new ThreadX();

        t.start();
        synchronized (t) {
            t.wait();
            System.out.println("l");
        }

        System.out.println("total: " + total);

    }
}

Antworten

10 akuzminykh Aug 16 2020 at 09:58

Antwort auf den Fragetext

Check out Thread#join(long):

[...] Wenn ein Thread beendet wird, wird die this.notifyAllMethode aufgerufen. [...]

Beachten Sie, Thread#join()dass diese Funktion mit aufgerufen wird 0, was für immer bedeutet.

[...] Eine Zeitüberschreitung von 0 bedeutet, für immer zu warten.

In Ihrem Fall wird hier also tnur aufgerufen, notifyAllwenn es beendet wird, wodurch der Haupt-Thread benachrichtigt wird, auf den gewartet wird t.


Dieses unintuitive Verhalten ist der Grund, warum sie Folgendes in die Dokumentation schreiben:

Es wird empfohlen , dass Anwendungen nicht verwenden wait, notifyoder notifyAllauf ThreadInstanzen.

Antwort auf den Fragentitel

Auschecken Object#wait(oder JLS (17.2.1. Warten) ):

Ein Thread kann aufwachen, ohne benachrichtigt, unterbrochen oder abgelaufen zu werden, ein sogenanntes falsches Aufwecken. Während dies in der Praxis selten vorkommt, müssen Anwendungen dagegen vorgehen, indem sie auf den Zustand testen, der das Aufwecken des Threads hätte verursachen sollen, und weiterhin warten, wenn der Zustand nicht erfüllt ist.

So können Threads in Java jederzeit aktiviert werden. Ein falsches Aufwachen ist nicht sehr wahrscheinlich , kann aber passieren.