In einigen Szenarien müssen wir warten, bis die Thread-Ausführung abgeschlossen ist, bevor wir mit dem nächsten Schritt fortfahren. Beispielsweise müssen einige Programme einige Ressourcen initialisieren, bevor sie mit der Ausführung beginnen. Zu diesem Zeitpunkt können wir einen Thread speziell für die Initialisierungsaufgabe starten und warten, bis die Thread-Aufgabe abgeschlossen ist, bevor wir andere Teile ausführen.
Zu diesem Zweck stellt uns die Thread-Klasse die Methode join() zur Verfügung. Wenn wir diese Methode mithilfe eines Thread-Objekts aufrufen, wird das aufrufende Thread-Objekt verzögert, bis die Ausführung des aufgerufenen Objekts abgeschlossen ist, bevor mit der Ausführung begonnen wird.
In diesem Abschnitt demonstriert das Beispielprogramm das Warten auf den Abschluss der Initialisierungsmethode, bevor andere Aufgaben ausgeführt werden.
weiß es
Befolgen Sie die unten aufgeführten Schritte, um das Beispielprogramm fertigzustellen.
1. Erstellen Sie eine Klasse mit dem Namen DataSourcesLoader und implementieren Sie die Runnable-Schnittstelle. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
Die öffentliche Klasse DataSourcesLoader implementiert Runnable {
2. Implementieren Sie die run()-Methode, geben Sie eine Nachricht an die Konsole aus, um den Start der Ausführung anzuzeigen, schlafen Sie dann 4 Sekunden lang und geben Sie dann eine Nachricht an die Konsole aus, um das Ende der Thread-Ausführung anzuzeigen. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
@Override
public void run() {
System.out.printf("Laden der Datenquellen beginnt: %s/n",
neues Datum());
versuchen {
TimeUnit.SECONDS.sleep(4);
} Catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Das Laden der Datenquellen wurde abgeschlossen: %s/n",
neues Datum());
}
3. Erstellen Sie eine Klasse mit dem Namen NetworkConnectionsLoader und implementieren Sie die Runnable-Schnittstelle. Implementieren Sie die run()-Methode. Der Code dieser Methode ist derselbe wie der run()-Methode der DataSourcesLoader-Klasse, außer dass sie 6 Sekunden lang ruht.
4. Implementieren Sie die Hauptklasse des Beispiels und implementieren Sie die Methode main(). Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse Main {
public static void main(String[] args) {
5. Erstellen Sie ein DataSourcesLoader-Objekt und ein Thread-Objekt, um dessen Ausführung zu starten. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourcesLoader");
6. Erstellen Sie ein NetworkConnectionsLoader-Objekt und ein Thread-Objekt, um dessen Ausführung zu starten. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionsLoader");
7. Rufen Sie die start()-Methode der beiden Thread-Objekte auf. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
thread1.start();
thread2.start();
8. Rufen Sie die Methode join() auf, um darauf zu warten, dass die beiden Threads ihre Aufgaben abschließen. Diese Methode löst eine InterruptedException aus, also fangen Sie diese Ausnahme ab. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
versuchen {
thread1.join();
thread2.join();
} Catch (InterruptedException e) {
e.printStackTrace();
}
9. Geben Sie einen Satz an die Konsole aus, um das Ende der Programmausführung anzuzeigen. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
System.out.printf("Main: Konfiguration wurde geladen: %s/n",
neues Datum());
10. Führen Sie das Programm aus und überprüfen Sie den Ausführungseffekt.
weiß warum
Wenn wir dieses Beispielprogramm ausführen, können wir sehen, wie zwei Threads mit der Ausführung beginnen. Zuerst schließt der DataSourcesLoader seine Ausführung ab; dann schließt der NetworkConnectionsLoader seine Ausführung ab. An diesem Punkt setzt der Hauptthread seine Ausführung fort und gibt dann eine Beendigungsmeldung an die Konsole aus.
niemals enden
Java bietet zwei weitere überladene join()-Methoden:
Kopieren Sie den Codecode wie folgt:
join(lange Millisekunden)
join(lange Millisekunden, lange Nanos)
Die erste Methode wartet nicht, bis der Aufruf die Aufgabe abschließt, sondern wartet die durch den Parameter angegebene Zeit ab, bevor sie mit der Ausführung beginnt. Wenn Thread1 beispielsweise diese Methode aufruft, thread1.join(1000), trifft Thread1 auf einen der folgenden Punkte: Die folgenden Bedingungen werden weiterhin ausgeführt:
1.thread2 schließt seine Ausführung ab;
2.Nach 1000 Millisekunden;
Wenn eine dieser beiden Bedingungen zutrifft, kehrt die Methode „join()“ zurück und führt die ursprüngliche Aufgabe weiter aus.
Die zweite Methode ist der ersten Methode sehr ähnlich, außer dass sie über einen zusätzlichen Nanosekunden-Zeitparameter verfügt.
Nutzen Sie die Lehre
Dieser Artikel wurde aus dem „Java 7 Concurrency Cookbook“ übersetzt (D Gua Ge hat ihn als „Java7 Concurrency Beispielsammlung“ gestohlen) und dient nur als Lernmaterial. Es darf ohne Genehmigung nicht für kommerzielle Zwecke verwendet werden.
Kleiner Erfolg
Die vollständige Version des in diesem Abschnitt verwendeten Beispielcodes.
Der vollständige Code der DataSourcesLoader-Klasse lautet wie folgt:
Paket com.diguage.books.concurrencycookbook.chapter1.recipe6;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* Datum: 19.09.2013
* Zeit: 09:15
*/
Die öffentliche Klasse DataSourcesLoader implementiert Runnable {
@Override
public void run() {
System.out.printf("Laden der Datenquellen beginnt: %s/n",
neues Datum());
versuchen {
TimeUnit.SECONDS.sleep(4);
} Catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Das Laden der Datenquellen wurde abgeschlossen: %s/n",
neues Datum());
}
}
Vollständiger Code der NetworkConnectionsLoader-Klasse
Kopieren Sie den Codecode wie folgt:
Paket com.diguage.books.concurrencycookbook.chapter1.recipe6;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* Datum: 19.09.2013
* Zeit: 09:21
*/
Die öffentliche Klasse NetworkConnectionsLoader implementiert Runnable {
@Override
public void run() {
System.out.printf("Laden der Datenquellen beginnt: %s/n",
neues Datum());
versuchen {
TimeUnit.SECONDS.sleep(6);
} Catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Das Laden der Datenquellen wurde abgeschlossen: %s/n",
neues Datum());
}
}
Der vollständige Code der Hauptklasse
Kopieren Sie den Codecode wie folgt:
Paket com.diguage.books.concurrencycookbook.chapter1.recipe6;
import java.util.Date;
/**
* Datum: 19.09.2013
* Zeit: 09:25
*/
öffentliche Klasse Main {
public static void main(String[] args) {
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourcesLoader");
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionsLoader");
thread1.start();
thread2.start();
versuchen {
thread1.join();
thread2.join();
} Catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Main: Konfiguration wurde geladen: %s/n",
neues Datum());
}
}