Dans certains scénarios, nous devons attendre la fin de l’exécution du thread avant de passer à l’étape suivante. Par exemple, certains programmes doivent initialiser certaines ressources avant de commencer leur exécution. À ce stade, nous pouvons démarrer un thread spécifiquement pour effectuer la tâche d'initialisation et attendre que la tâche du thread soit terminée avant d'exécuter d'autres parties.
Pour cela, la classe Thread nous fournit la méthode join(). Lorsque nous appelons cette méthode à l'aide d'un objet thread, l'objet thread appelant sera retardé jusqu'à ce que l'objet appelé termine son exécution avant de commencer l'exécution.
Dans cette section, l'exemple de programme montre l'attente de la fin de la méthode d'initialisation avant d'effectuer d'autres tâches.
je le sais
Suivez les étapes indiquées ci-dessous pour terminer l’exemple de programme.
1. Créez une classe nommée DataSourcesLoader et implémentez l'interface Runnable. Le code est le suivant :
Copiez le code comme suit :
la classe publique DataSourcesLoader implémente Runnable {
2. Implémentez la méthode run(), imprimez un message sur la console pour indiquer le début de l'exécution, puis dormez pendant 4 secondes, puis imprimez un message sur la console pour indiquer la fin de l'exécution du thread. Le code est le suivant :
Copiez le code comme suit :
@Outrepasser
public void run() {
System.out.printf("Début du chargement des sources de données : %s/n",
nouvelle date());
essayer {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Le chargement des sources de données est terminé : %s/n",
nouvelle date());
}
3. Créez une classe nommée NetworkConnectionsLoader et implémentez l'interface Runnable. Implémentez la méthode run(). Le code de cette méthode est le même que la méthode run() de la classe DataSourcesLoader, sauf qu'elle dort pendant 6 secondes.
4. Implémentez la classe principale de l'exemple et implémentez la méthode main(). Le code est le suivant :
Copiez le code comme suit :
classe publique Principale {
public static void main (String[] arguments) {
5. Créez un objet DataSourcesLoader et un objet Thread pour démarrer son exécution. Le code est le suivant :
Copiez le code comme suit :
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = nouveau Thread(dsLoader, "DataSourcesLoader");
6. Créez un objet NetworkConnectionsLoader et un objet Thread pour démarrer son exécution. Le code est le suivant :
Copiez le code comme suit :
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = nouveau Thread(ncLoader, "NetworkConnectionsLoader");
7. Appelez la méthode start() des deux objets Thread. Le code est le suivant :
Copiez le code comme suit :
thread1.start();
thread2.start();
8. Appelez la méthode join() pour attendre que les deux threads terminent leurs tâches. Cette méthode lancera InterruptedException, alors interceptez cette exception. Le code est le suivant :
Copiez le code comme suit :
essayer {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
9. Imprimez une phrase sur la console pour indiquer la fin de l'exécution du programme. Le code est le suivant :
Copiez le code comme suit :
System.out.printf("Principal : La configuration a été chargée : %s/n",
nouvelle date());
10. Exécutez le programme et vérifiez l'effet d'exécution.
sais pourquoi
Lors de l'exécution de cet exemple de programme, nous pouvons voir deux threads commencer leur exécution. Tout d’abord, le DataSourcesLoader termine son exécution ; ensuite, le NetworkConnectionsLoader termine son exécution. À ce stade, le thread principal continue son exécution puis imprime un message de fin sur la console.
sans fin
Java fournit deux autres méthodes join() surchargées :
Copiez le code comme suit :
rejoindre (longues millisecondes)
rejoindre (longues millisecondes, longues nanos)
La première méthode n'attend pas l'appel pour terminer la tâche, mais attend le temps spécifié par le paramètre avant de commencer l'exécution, par exemple, si thread1 appelle cette méthode, thread1.join(1000), lorsque le thread thread1 rencontre l'un des les conditions suivantes continueront à s'exécuter :
1.thread2 termine son exécution ;
2. Après 1000 millisecondes ;
Lorsque l'une de ces deux conditions est vraie, la méthode join() reviendra et continuera à exécuter la tâche d'origine.
La deuxième méthode est très similaire à la première méthode, sauf qu’elle comporte un paramètre de temps supplémentaire de l’ordre de la nanoseconde.
Utiliser la doctrine
Cet article est traduit du "Java 7 Concurrency Cookbook" (D Gua Ge l'a volé sous le nom de "Java7 Concurrency Sample Collection") et n'est utilisé que comme matériel d'apprentissage. Il ne peut être utilisé à des fins commerciales sans autorisation.
Petit succès
La version complète de l’exemple de code utilisé dans cette section.
Le code complet de la classe DataSourcesLoader est le suivant :
package com.diguage.books.concurrencycookbook.chapter1.recipe6 ;
importer java.util.Date ;
importer java.util.concurrent.TimeUnit ;
/**
* Date : 2013-09-19
* Heure : 09h15
*/
la classe publique DataSourcesLoader implémente Runnable {
@Outrepasser
public void run() {
System.out.printf("Début du chargement des sources de données : %s/n",
nouvelle date());
essayer {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Le chargement des sources de données est terminé : %s/n",
nouvelle date());
}
}
Code complet de la classe NetworkConnectionsLoader
Copiez le code comme suit :
package com.diguage.books.concurrencycookbook.chapter1.recipe6 ;
importer java.util.Date ;
importer java.util.concurrent.TimeUnit ;
/**
* Date : 2013-09-19
* Heure : 09h21
*/
classe publique NetworkConnectionsLoader implémente Runnable {
@Outrepasser
public void run() {
System.out.printf("Début du chargement des sources de données : %s/n",
nouvelle date());
essayer {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Le chargement des sources de données est terminé : %s/n",
nouvelle date());
}
}
Le code complet de la classe Main
Copiez le code comme suit :
package com.diguage.books.concurrencycookbook.chapter1.recipe6 ;
importer java.util.Date ;
/**
* Date : 2013-09-19
* Heure : 09h25
*/
classe publique Principale {
public static void main (String[] arguments) {
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = nouveau Thread(dsLoader, "DataSourcesLoader");
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = nouveau Thread(ncLoader, "NetworkConnectionsLoader");
thread1.start();
thread2.start();
essayer {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Principal : La configuration a été chargée : %s/n",
nouvelle date());
}
}