Die Thread.join () - Methode in Java

Die Thread.join () -Methode in Java

 

1. Überblick

In diesem Tutorial werden die verschiedenen Methoden vonjoin()in der KlasseThreaderläutert. Wir werden auf die Details dieser Methoden und einige Beispielcodes eingehen.

Wie diewait() undnotify() methods istjoin() ein weiterer Mechanismus der Synchronisation zwischen Threads.

Sie können einen kurzen Blick aufthis tutorial werfen, um mehr überwait() undnotify() zu erfahren.

2. DieThread.join()-Methode

Die Join-Methode ist in der KlasseThreaddefiniert:

public final void join () löst InterruptedException aus Wartet darauf, dass dieser Thread stirbt.

Wenn wir die Methodejoin()für einen Thread aufrufen, geht der aufrufende Thread in einen Wartezustand über. Es bleibt in einem Wartezustand, bis der referenzierte Thread beendet wird.

Wir können dieses Verhalten im folgenden Code sehen:

class SampleThread extends Thread {
    public int processingCount = 0;

    SampleThread(int processingCount) {
        this.processingCount = processingCount;
        LOGGER.info("Thread Created");
    }

    @Override
    public void run() {
        LOGGER.info("Thread " + this.getName() + " started");
        while (processingCount > 0) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                LOGGER.info("Thread " + this.getName() + " interrupted");
            }
            processingCount--;
        }
        LOGGER.info("Thread " + this.getName() + " exiting");
    }
}

@Test
public void givenStartedThread_whenJoinCalled_waitsTillCompletion()
  throws InterruptedException {
    Thread t2 = new SampleThread(1);
    t2.start();
    LOGGER.info("Invoking join");
    t2.join();
    LOGGER.info("Returned from join");
    assertFalse(t2.isAlive());
}

Wir sollten bei der Ausführung des Codes ähnliche Ergebnisse erwarten wie die folgenden:

INFO: Thread Created
INFO: Invoking join
INFO: Thread Thread-1 started
INFO: Thread Thread-1 exiting
INFO: Returned from join

The join() method may also return if the referenced thread was interrupted. In diesem Fall wirft die Methode einInterruptedException.

Schließlichif the referenced thread was already terminated or hasn’t been started, the call to join() method returns immediately.

Thread t1 = new SampleThread(0);
t1.join();  //returns immediately

3. Thread.join() Methoden mit Timeout

Die Methodejoin()wartet weiter, wenn der referenzierte Thread blockiert ist oder die Verarbeitung zu lange dauert. Dies kann zu einem Problem werden, da der aufrufende Thread nicht mehr reagiert. Um diese Situationen zu bewältigen, verwenden wir überladene Versionen derjoin()-Methode, mit denen wir eine Zeitüberschreitung angeben können.

Es gibt zweitimed versions, die diejoin()-Methode überladen:

“public final void join(long millis_) löst InterruptedException_Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.” aus

“public final void join(long millis, int nanos_) löst InterruptedException_Waits at most millis milliseconds plus nanos_ Nanosekunden aus, damit dieser Thread stirbt. ”_

Wir können die zeitgesteuertenjoin() wie folgt verwenden:

@Test
public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout()
  throws InterruptedException {
    Thread t3 = new SampleThread(10);
    t3.start();
    t3.join(1000);
    assertTrue(t3.isAlive());
}

In diesem Fall wartet der aufrufende Thread ungefähr 1 Sekunde, bis der Thread t3 beendet ist. Wenn der Thread t3 in diesem Zeitraum nicht beendet wird, gibt die Methodejoin()die Kontrolle an die aufrufende Methode zurück.

Timedjoin() ist für das Timing vom Betriebssystem abhängig. Wir können also nicht davon ausgehen, dassjoin() genau so lange wartet, wie angegeben.

4. Thread.join() Methoden und Synchronisation

Zusätzlich zum Warten bis zur Beendigung hat der Aufruf der Methodejoin()einen Synchronisationseffekt. join() creates a happens-before relationship:

„Alle Aktionen in einem Thread werden ausgeführt, bevor ein anderer Thread erfolgreich von einem join () in diesem Thread zurückgegeben wird.“

Dies bedeutet, dass wenn ein Thread t1 t2.join () aufruft, alle von t2 vorgenommenen Änderungen bei der Rückkehr in t1 sichtbar sind. Wenn wir jedoch nichtjoin() aufrufen oder andere Synchronisationsmechanismen verwenden, können wir nicht garantieren, dass Änderungen im anderen Thread für den aktuellen Thread sichtbar sind, selbst wenn der andere Thread abgeschlossen ist.

Obwohl der Methodenaufrufjoin()für einen Thread im terminierten Zustand sofort zurückgegeben wird, müssen wir ihn in einigen Situationen dennoch aufrufen.

Im Folgenden sehen Sie ein Beispiel für falsch synchronisierten Code:

SampleThread t4 = new SampleThread(10);
t4.start();
// not guaranteed to stop even if t4 finishes.
do {

} while (t4.processingCount > 0);

Um den obigen Code richtig zu synchronisieren, können wir zeitgesteuertet4.join() innerhalb der Schleife hinzufügen oder einen anderen Synchronisationsmechanismus verwenden.

5. Fazit

Die Methode vonjoin()ist sehr nützlich für die Synchronisation zwischen Threads. In diesem Artikel haben wir diejoin() Methoden und ihr Verhalten diskutiert. Wir haben den Code auch mit derjoin()-Methode überprüft.

Wie immer kann der vollständige Quellcodeover on GitHub gefunden werden.