[FIXED] Methoden zum Warten und Benachrichtigen von Java-Threads

Ausgabe

Ich lerne für OCJP und bin jetzt im Kapitel “Thread”. Ich habe einige Fragen zu Warte- und Benachrichtigungsmethoden. Ich glaube, ich verstehe, was hier passiert, aber ich möchte nur sichergehen, dass ich auf dem richtigen Weg bin. Ich habe diesen Code als Beispiel geschrieben:

package threads;

public class Main {

    static Object lock = new Object();

    public static void main(String[] args) {
        new Main().new FirstThread().start();
        new Main().new SecondThread().start();
    }

    class FirstThread extends Thread {
        public void run() {
            synchronized (lock) {
                lock.notify();
                System.out.println("I've entered in FirstThread");
            }
        }
    }
    class SecondThread extends Thread {
        public void run() {
            synchronized (lock) {
                try {
                    lock.wait();
                    System.out.println("I'm in the second thread");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

In diesem Beispiel ist die Konsolenausgabe I've entered in FirstThread, da der erste Thread startet, die Methode translate() aufgerufen wird, dann der zweite Thread startet, die Methode wait() aufgerufen wird und der String “I’m in the second thread” nicht ausgegeben wird .

Das nächste Szenario ist, dass ich die Positionen von umkehre new Main().new FirstThread().start();und new Main().new SecondThread().start();die Ausgabe ist

I've entered in FirstThread
I'm in the second thread

Da der zweite Thread startet, wird die Methode wait() aufgerufen, dann startet der erste Thread, die Methode notification() wird aufgerufen, die Konsole I've entered in FirstThreadgibt aus, das Warten wird freigegeben und I'm in the second threadin der Konsole ausgegeben.

Geschieht das, weil der Computer so schnell ist und die Threads sequentiell ablaufen? Theoretisch kann die zweite start()-Methode meiner Meinung nach zuerst aufgerufen werden, oder?.

Und die letzte Frage, die ich habe, ist, warum das Sperrobjekt statisch sein muss, denn wenn ich den statischen Modifikator entferne, ist die Ausgabe immer I've entered in FirstThread?

Ich weiß, dass statische Felder in JVM geladen werden, wenn die Klasse geladen wird, aber ich kann die Logik von lock Object nicht verstehen.

Lösung

Die Threads werden nacheinander gestartet, und theoretisch würde Thread 1 vor Thread 2 ausgeführt werden, obwohl dies nicht garantiert ist (ziemlich sicher, dass es in diesem einfachen Fall konsistent sein wird, da es keine echten oder simulierten aleatorischen Verzögerungen gibt).

Aus diesem Grund hat Thread 2, wenn er etwas früher gestartet wird, die Möglichkeit, auf eine Sperre zu warten, die anschließend (von Thread 1) benachrichtigt wird, anstatt ewig auf eine Sperre zu warten, die bereits einmal benachrichtigt wurde (daher kein Drucken).

Auf der staticSperre Object: Sie binden Ihre [First/Second]Threadverschachtelten Klassen an Instanzen von Main, daher muss die Sperre beiden gemeinsam sein, wenn Sie möchten, dass sie mit derselben Sperre synchronisiert werden.

Wenn es sich um ein Instanzobjekt handeln würde, würden Ihre Threads auf eine andere Sperre zugreifen und sie synchronisieren, da Ihr new Main()...Idiom zwei Instanzen von Mainund anschließend zwei Instanzen von erhalten würde lock.


Beantwortet von –
Mena


Antwort geprüft von –
Jay B. (FixError Admin)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like