Professional Documents
Culture Documents
10 Threads
10 Threads
de casablanca
Ecole supérieure de technologie
Programmation
orientée objet
Java Avancé
Préparé par :
Larbi Hassouni
Threads En Java
HASSOUNI Larbi 2
Définitions
• Un programme est multitâche quand il lance
(ou peut lancer) l’exécution de plusieurs
parties de son code en même temps
• A un moment donné, il comporte plusieurs
points d’exécution liés aux différentes
parties qui s'exécutent en parallèle
HASSOUNI Larbi 3
Systèmes d’exploitation
• Tous les systèmes d'exploitation modernes
sont multitâches et ils permettent l’exécution
de programmes multitâches
• Sur une machine monoprocesseur cette
exécution en parallèle est simulée
• Si le système est préemptif, il peut à tout
moment prendre la main à un programme
pour la donner à un autre
• Sinon, un programme garde la main jusqu’à ce
qu’il la cède à un autre
HASSOUNI Larbi 4
Threads et processus
• Le multitâche s'appuie sur les processus ou les
threads (processus légers)
• Chaque processus a son propre espace
mémoire (espace où sont rangées les valeurs
des variables utilisées par le processus)
• Un processus peut lancer plusieurs threads qui
se partagent le même espace mémoire et
peuvent donc se partager des variables
• Un thread prend moins de ressources système
qu’un processus
HASSOUNI Larbi 5
Exemples de thread
• L’interface graphique de l’utilisateur lance un
thread pour charger une image et continue à
traiter les événements générés par les actions
de l’utilisateur
• Le serveur réseau qui attend les demandes de
connexions venant des autres machines lance
un thread pour traiter chacune des demandes
• La multiplication de 2 matrices (m, p) et (p, n)
peut être effectuée en parallèle par m n
threads
HASSOUNI Larbi 6
Utilité du multitâche
• Sur une machine multiprocesseurs il permet
d’améliorer les performances en répartissant les
différentes tâches sur différents processeurs
• Par exemple, le calcul du produit de 2 matrices
peut être réparti en un nombre de tâches
parallèles égal au nombre de processeurs,
• La répartition des tâches sur les processeurs est
le plus souvent faite automatiquement par le
système qui offre le multitâche
HASSOUNI Larbi 7
Utilité du multitâche (2)
• Sur une machine monoprocesseur, il peut aussi être
intéressant d’utiliser le multitâche pour
– modéliser plus simplement (simulation par
exemple)
– profiter des temps de pose d’une tâche (attente
d’entrées-sorties ou d’une action de l’utilisateur)
pour exécuter d’autres tâches
– réagir plus vite aux actions de l’utilisateur en
rejetant une tâche longue et non-interactive dans
un autre thread (par exemple, chargement d’une
image ou lecture de données qui proviennent
d’un réseau)
HASSOUNI Larbi 8
Programme comportant 3 threads
Système à multi processeurs Système à un seul processeurs
HASSOUNI Larbi 9
Comment opèrent les threads
HASSOUNI Larbi 10
HASSOUNI Larbi 11
Problèmes du multitâche
HASSOUNI Larbi 12
Java et le multitâche
HASSOUNI Larbi 13
Définiton desThreads en Java
HASSOUNI Larbi 14
Interface Runnable
HASSOUNI Larbi 15
Contrôleur de thread
HASSOUNI Larbi 16
Classe Thread
HASSOUNI Larbi 17
Classe Thread:
Constructeurs généralement utilisés
• Thread()
• Thread(String name)
• Thread(Runnable r)
• Thread(Runnable r,String name)
HASSOUNI Larbi 18
Thread()Allocates a new Thread object.
Thread(ThreadGroup group, Runnable target, String name)Allocates a new Thread object so that
it has target as its run object, has the specified name as its name, and belongs to the thread group
referred to by group.
HASSOUNI Larbi 19
2 façons de créer
un contrôleur de thread
HASSOUNI Larbi 20
Créer un contrôleur de thread avec
une classe fille de la classe Thread
class ThreadTache extends Thread {
. . .
public void run() {
// Code qui sera exécuté par le thread
. . .
}
}
HASSOUNI Larbi 21
Créer un contrôleur de thread
avec l'interface Runnable
class Tache implements Runnable {
. . .
public void run() {
// Code qui sera exécuté par le thread
. . .
}
}
HASSOUNI Larbi 22
Quelle façon utiliser ?
HASSOUNI Larbi 24
public int getPriority(): retourne la priorité du thread.
HASSOUNI Larbi 25
public boolean isAlive(): teste si le thread est toujours en vie.
public void yield(): Met le thread en cours d'exécution en état de
pause temporaire pour permettre à d'autres thread de priorité
égale ou supérieure de s'exécuter.
public boolean isDaemon(): teste si le thread est un thread
demons.
public void setDaemon(boolean b): marque le thread comme un
thread demons (b=true) ou utilisateur (b=false). Par défaut un
nouveau thread est un thread utilisateur.
public void interrupt(): interrompe un thread, plus exactement,
positionne le flag d'interruption d'un thread à l'état "ON".
public boolean isInterrupted(): teste si le thread a été
interrompu. Autrement dit, teste si son flag d'interruption est
positionné à "ON".
public static boolean interrupted(): idem que isInterrupted(),
mais c'est une méthode statique.
HASSOUNI Larbi 26
Etats d'un thread
A thread can be in one of the following states:
• NEW : A thread that has not yet started is in this state
• RUNNABLE : A thread in the runnable state is executing in the Java virtual machine
but it may be waiting for other resources from the operating system such as
processor.
• BLOCKED: A thread in the blocked state is waiting for a monitor lock to enter a
synchronized block/method or reenter a synchronized block/method after calling
object.wait.
• WAITING : A thread is in the waiting state due to calling one of the following
methods:
– Object.wait with no timeout
– Thread.join with no timeout
A thread in the waiting state is waiting for another thread to perform a particular action.
For example, a thread that has called Object.wait() on an object is waiting for another
thread to call Object.notify() or Object.notifyAll() on that object. A thread that has
called Thread.join() is waiting for a specified thread to terminate
HASSOUNI Larbi 27
TIMED_WAITING : A thread is in the timed waiting
state due to calling one of the following methods
with a specified positive waiting time:
•Thread.sleep
•Object.wait with timeout
•Thread.join with timeout
HASSOUNI Larbi 28
Cycle de vie d'un thread Bloqué
(BLOCKED)
Ne perd pas
Bloqué le moniteur
(BLOCKED)
new Perd le Moniteur wait()
Thread() sleep()
notify()
HASSOUNI Larbi 29
Nom d’un thread
HASSOUNI Larbi 30
Lancer l’exécution d'un thread
La méthode start() de la classe Thread est utilisée pour lancer
un thread nouvellement créé. Elle effectue les operations
suivantes:
❑ Un nouveau thread démarre (avec une nouvelle
"callstack").
❑ Le thread passe de l'état "New" à l'état "Runnable".
Lorsque le thread est sélectioné par le scheduler, sa méthode
run() se met en exécution en parallèle avec le code qui a
lance le thread.
Attention, une erreur serait d’appeler directement la méthode
run() : la méthode run() serait exécutée par le thread qui l’a
appelée et pas par un nouveau thread(Il n’ya pas création de
thread)
HASSOUNI Larbi 31
• Chaque thread lancé avec start possède sa propre
pile (call stack).
• Invoquer la méthode run() à partir du thread main(),
run() utilise la pile actuelle utilisée par le tread
main() plutôt que d'utiliser une nouvelle pile.
Invocation de run() à
Lancement des threads par start:
partir de main(): run() se
Chaque thread s'exécute avec une pile séparée
partage la même pile que
main()
HASSOUNI Larbi 32
Relancer un thread
Attention :
• On ne peut relancer un thread qui a déjà été lancé.
• Que l’exécution de la méthode run du thread soit
terminée ou non, si on relance un thread, on obtient
une java.lang.IllegalThreadStateException
HASSOUNI Larbi 33
Le "Scheduler" des threads en Java
• Le Scheduler des threads en java est la partie de la
JVM qui décide quel thread sera mis en exécution.
• Il n'y a pas de garantie sur le thread "runnable" qui
sera séléctioné par le Scheduler pour s'exécuter.
• Le Scheduler des threads utilise principalement deux
méthodes pour planifier l'exécution des threads :
– Planification "preemptive"
– "time slicing" ou quantum de temp.
HASSOUNI Larbi 34
Différence entre planification preemptive
et time slicing
• Sous la planification preemptive, le thread qui a la
plus haute priorité s'exécute jusqu'à ce qu'il se met
en état d'attente, ou se termine, ou un thread de
plus haute priorité rentre en existence.
• Sous "time slicing", un thread s'exécute pour une
partie du temps (quantum), puis rentre dans la
queue (ou pool) des treads runnable. Le scheduler
détermine par la suie quel thread se mettra en
exécution, en se basant sur la priorité et d'autres
facteurs.
HASSOUNI Larbi 35
Threads : Exemple 1
class Ecrit extends Thread{ public class TstThr1{
public static void main (String args[]){
public Ecrit (String texte, int nb, long attente){ Ecrit e1 = new Ecrit ("Salam\n", 10, 5) ;
this.texte = texte ; Ecrit e2 = new Ecrit ("Hello\n", 12, 10) ;
this.nb = nb ; Ecrit e3 = new Ecrit ("Bonjour\n", 5, 15) ;
this.attente = attente ; e1.start() ;
e2.start() ;
} e3.start() ;
public void run (){ System.out.println(« Je suis la fonction main »);
}
try{ }
for (int i=0 ; i<nb ; i++){
System.out.print (texte) ;
sleep (attente) ;
}
}
catch (InterruptedException e) {
} // impose par sleep
}
private String texte ;
private int nb ;
private long attente ;
} HASSOUNI Larbi 36
Threads : Exemple 2
class Ecrit implements Runnable{ public class TstThr2{
public static void main (String args[]){
public Ecrit (String texte, int nb, long attente){ Ecrit e1 = new Ecrit ("Salam\n", 10, 5) ;
this.texte = texte ; Ecrit e2 = new Ecrit ("Hello\n", 12, 10) ;
this.nb = nb ; Ecrit e3 = new Ecrit ("Bonjour\n", 5, 15) ;
this.attente = attente ;
Thread t1 = new Thread (e1) ; t1.start() ;
} Thread t2 = new Thread (e2) ; t2.start() ;
public void run (){ Thread t3 = new Thread (e3) ; t3.start() ;
try{ System.out.println(“Je suis la fonction main”);
}
for (int i=0 ; i<nb ; i++){ }
System.out.print (texte) ;
Thread.sleep (attente) ;
// attention Thread.sleep
}
}
catch (InterruptedException e) {
} // impose par sleep
}
private String texte ;
private int nb ;
private long attente ;
}
HASSOUNI Larbi 37
HASSOUNI Larbi 38
Threads : Exemple 3
class Ecrit implements Runnable{ public class TstThr3{
public Ecrit (String texte, int nb, long attente){ public static void main (String args[]){
Ecrit e1 = new Ecrit ("Salam\n", 10, 5) ;
this.texte = texte ; Ecrit e2 = new Ecrit ("Hello\n", 12, 10) ;
this.nb = nb ; Ecrit e3 = new Ecrit ("Bonjour\n", 5, 15) ;
this.attente = attente ; e1.start() ;
} e2.start() ;
public void start (){ e3.start() ;
Thread t = new Thread (this) ; System.out.println(« Je suis la fonction main »);
t.start() ; }
}
}
public void run (){
try{
for (int i=0 ; i<nb ; i++){
System.out.print (texte) ;
Thread.sleep (attente) ;
}
}
catch (InterruptedException e) {
} // impose par sleep
}
private String texte ;
private int nb ;
private long attente ;
} HASSOUNI Larbi 39
Threads : Exemple 4
class Ecrit implements Runnable{ public class MyTstThr4{
public Ecrit (String texte, int nb, long attente){ public static void main (String args[]){
this.texte = texte ; Ecrit e1 = new Ecrit ("Salam\n", 10, 5) ;
Ecrit e2 = new Ecrit ("Hello\n", 12, 10) ;
this.nb = nb ; Ecrit e3 = new Ecrit ("Bonjour\n", 5, 15) ;
this.attente = attente ;
} Thread t1 = new Thread (e1) ; t1.start() ;
public void run (){ Thread t2 = new Thread (e2) ; t2.start() ;
try{ Thread t3 = new Thread (e3) ; t3.start() ;
for (int i=0 ; i<nb ; i++){
System.out.print (texte) ; try{
for(int i=0; i<5; i++){
Thread.sleep (attente) ; System.out.println("Fonction main");
// attention Thread.sleep Thread.sleep(100);
} }
} }
catch (InterruptedException e) { catch(InterruptedException e){
} // impose par sleep }
}
System.out.println("Je suis la fonction main");
private String texte ;
private int nb ; }
private long attente ; }
}
HASSOUNI Larbi 40
Types de Threads
• On distingue deux types de threads
– les threads utilisateur
– les démons
• La différence :
– la JVM fonctionne tant qu’il reste des threads
utilisateurs en exécution
– la JVM s’arrête s’il ne reste plus que des démons
HASSOUNI Larbi 41
Thread démons
(Daemon Thread)
• Un thread "Daemon" en java est un thread
fournisseur de service qui fournit des services au
thread utilisateur. Son cycle de vie dépend du cycle
de vie des threads utilisateurs.
• Lorsque tous les threads utilisateurs meurent, La JVM
termine automatiquement les threads démons.
• Il y a beucoup de threads démons qui s'exécutent
automatiquement (gc : garbage collector, finalize :
finalizer, …etc). (Pour voir tous les details, utilizer
l'utilitaire "jconsole")
HASSOUNI Larbi 42
Points à retenir sur les threads démons
HASSOUNI Larbi 43
Threads démons
• La méthode:
void setDaemon(boolean true)
de la classe Thread permet d’indiquer que le
thread sera un démon (thread utilisateur par
défaut)
• Elle doit être appelée avant le démarrage du
thread par l’appel de start()
HASSOUNI Larbi 44
HASSOUNI Larbi 45
Threads demons et arret brutal
class Ecrit extends Thread import java.util.Scanner;
{ public Ecrit (String texte, long attente) public class Demons
{ this.texte = texte ; { public static void main (String args[])
this.attente = attente ; { Ecrit e1 = new Ecrit ("Salam\n", 5) ;
} Ecrit e2 = new Ecrit ("Hello\n", 10) ;
Ecrit e3 = new Ecrit ("Bonjour\n", 35) ;
public void run ()
e1.setDaemon (true) ; e1.start() ;
{ try e2.setDaemon (true) ; e2.start() ;
{ while (true) // boucle infinie e3.setDaemon (true) ; e3.start() ;
{ if (interrupted()) return ; int n = new Scanner(System.in).nextInt() ;
System.out.print (texte) ; // met fin au main, donc ici aux trois autres threads démons
sleep (attente) ; }
} }
}
catch (InterruptedException e)
{ return ; // on peut omettre return ici Exécuter le en mode
} console
}
HASSOUNI Larbi 46
Threads : Exemple 5 (1/2)
import java.io.IOException;
public class TryThread extends Thread {
public TryThread(String firstName, String secondName, long delay) {
this.firstName = firstName; // Store the first name
this.secondName = secondName; // Store the second name
this.aWhile = delay; // Store the delay
setDaemon(true); } // Thread is daemon
public static void main(String[] args) {
// Create three threads
Thread first = new TryThread(« Said ", « AOUITA ", 200L);
Thread second = new TryThread(« Younes ", « ELAYNAOUI ", 300L);
Thread third = new TryThread(« Nawal ", « MOUTAWAKIL ", 500L);
System.out.println("Press Enter when you have had enough...\n");
first.start(); second.start(); third.start(); // Start the third thread
try {
System.in.read(); // Wait until Enter key pressed
System.out.println("Enter pressed...\n");
} catch (IOException e) { // Handle IO exception
System.err.println(e); // Output the exception }
System.out.println("Ending main()");
return;
}
HASSOUNI Larbi 47
Threads : Exemple 5 (2/2)
HASSOUNI Larbi 48
Threads : Exemple 6 (1/2)
import java.io.IOException;
public class JumbleNames implements Runnable {
// Constructor
public JumbleNames(String firstName, String secondName, long delay) {
this.firstName = firstName; // Store the first name
this.secondName = secondName; // Store the second name
aWhile = delay; // Store the delay
}
// Method where thread execution will start
public void run() {
try {
while(true) {
System.out.print(firstName);
Thread.sleep(aWhile);
System.out.print(secondName+"\n");
}
} catch(InterruptedException e) {
System.out.println(firstName + secondName + e);
} }
HASSOUNI Larbi 49
Threads : Exemple 6 (2/2)
public static void main(String[] args) {
// Create three threads
Thread first = new Thread(new JumbleNames("Hopalong ", "Cassidy ", 200L));
Thread second = new Thread(new JumbleNames("Marilyn ", "Monroe ", 300L));
Thread third = new Thread(new JumbleNames("Slim ", "Pickens ", 500L));
// Set threads as daemon
first.setDaemon(true); second.setDaemon(true); third.setDaemon(true);
System.out.println("Press Enter when you have had enough...\n");
first.start(); // Start the first thread
second.start(); // Start the second thread
third.start(); // Start the third thread
try {
System.in.read(); // Wait until Enter key pressed
System.out.println("Enter pressed...\n");
} catch (IOException e) { // Handle IO exception
System.err.println(e); // Output the exception
}
System.out.println("Ending main()"); return;
}
private String firstName; private String secondName; private long aWhile;}
HASSOUNI Larbi 50
Dormir
• La méthode static de la classe Thread
public static void sleep(long millis)
throws InterruptedException
fait dormir le thread qui l'appelle un certain nombre
de millisecondes
• Si elle est exécutée dans du code synchronisé, le
thread ne perd pas le moniteur (au contraire de wait())
• La syntaxe est :
public static void sleep(int millis) throws InterruptedException
Exception
•InterruptedException -- Si le thread en cours est interrompu par un autre
thread, l’exception InterruptedException est lancée et son flag d’interruption est
initialisé.
HASSOUNI Larbi 51
Attente de la fin d’un thread
• Si dans un thread vous voulez attendre jusquà ce qu’un
autre thread meurt, vous pouvez appeler la méthode
join() pour le thread à attendre.
• La syntaxe est:
➢ threadAattendre.join(); : Le thread en cours attend
jusqu’à ce que threadAAttendre meurt;
➢ threadAattendre.join(long millis);
➢ threadAattendre.join(long millis, int nanos);
• La méthode join() peut lancer l’exception
InterruptedException si le thread en cours est interrompu
par un autre thread, par consequent vous devez mettre
dans un bloc try block et capter (catch) l’exception.
HASSOUNI Larbi 52
class FaitQuelqueChose implements Runnable {
// attribut propre au thread
protected String msg;
// constructeur
public FaitQuelqueChose(String msg) {
this.msg = msg;
}
// méthode d’exécution de la thread
public void run(){
System.out.println("run: (" + msg + ") début !");
try {
Thread.sleep(5000);
}
catch (Exception e) {}
System.out.println("run: (" + msg + ") milieu...");
try {
Thread.sleep(5000);
}
catch (Exception e) {}
System.out.println("run: (" + msg + ") fin !");
}
}
HASSOUNI Larbi 53
public class ThreadEx {
public static void main(String[] args) throws Exception {
System.out.println("main: demarre un");
Thread t1 = new Thread(new FaitQuelqueChose("un"));
t1.start();
try {
Thread.sleep(2500);
}
catch (Exception e) {}
System.out.println("main: demarre deux");
HASSOUNI Larbi 55
Exécution de ThreadEx
C:\>java MineThreadEx
HASSOUNI Larbi 60
Exécution de TstIntr
bonsoir bonjour
** Arret premier thread **
main : avant interruption e2
HASSOUNI Larbi 61
Partage de données
entre plusieurs threads
• Le plus simple est de créer les threads
en utilisant une classe qui implémente
Runnable et de mettre les données
partagées comme variables static
de cette classe.
HASSOUNI Larbi 62
Synchronisation entre threads
HASSOUNI Larbi 63
Dans ce qui suit, nous allons discuter les capacités
basiques du langage Java pour gérer la synchronisation
entre les threads.
La librairie de concurrence fournie par les packages:
• java.util. concurrent,
• java.util.concurrent.atomic,
• java.util.concurrent.locks
Contient des classes qui implémente des facilités de
gestion des threads spécialisées,
HASSOUNI Larbi 64
Section critique
• L’utilisation de threads peut entraîner des
besoins de synchronisation pour éviter les
problèmes liés aux accès simultanés aux
variables
• En programmation, on appelle section critique
une partie du code qui ne peut être exécutée
en même temps par plusieurs threads sans
risquer de provoquer des anomalies de
fonctionnement
HASSOUNI Larbi 65
Exemple de problème
• Si x = 2, le code x = x + 1;
exécuté par 2 threads, peut donner en fin
d’exécution 3 ou 4 suivant l’ordre d’exécution :
1. T1 : lit la valeur de x (2)
2. T2 : lit la valeur de x (2)
3. T1 : calcul de x + 1 (3)
4. T2 : calcul de x + 1 (3)
5. T1 : range la valeur calculée dans x (3)
6. T2 : range la valeur calculée dans x (3)
• x contient 3 au lieu de 4 !
HASSOUNI Larbi 66
Synchronisation
• Il faut donc éviter l’exécution simultanée de
sections de code critiques par plusieurs threads
HASSOUNI Larbi 67
Méthodes synchronized
class MyClass {
synchronized public void method1() {
// Code for the method...
}
synchronized public void method2() {
// Code for the method...
}
public void method3() {
// Code for the method...
}
}
HASSOUNI Larbi 68
HASSOUNI Larbi 69
Synchronisation de threads
class Nombres {
public void calcul() {
n++ ;
carre = n*n ;
}
public void affiche () {
System.out.println (n + " a pour carre " + carre) ;
}
private int n=0, carre ;
}
HASSOUNI Larbi 75
Moniteur ou verrou d’un objet
HASSOUNI Larbi 76
Synchronisation avec les moniteurs
HASSOUNI Larbi 78
Exemple
public class Compte {
private double solde;
HASSOUNI Larbi 79
Exemple (suite)
• On lance 3 threads du type suivant :
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) {
compte.deposer(1000);
}
}
};
• A la fin de l’exécution, on n’obtient pas nécessairement
300.000
• Il faut rendre deposer (et getSolde) synchronisée :
public synchronized
void deposer(double somme)
HASSOUNI Larbi 80
Synchronisation et performances
• L’exécution de code synchronisé nuit aux
performances
• Surtout s’il provoque des blocages entre
threads ; si pas de blocage, peu de perte de
performance
• Mais, de plus, du code synchronisé peut
empêcher des optimisations (inlining) au
moment de la compilation
HASSOUNI Larbi 81
Méthodes statiques
HASSOUNI Larbi 82
Méthode synchronisée et héritage
HASSOUNI Larbi 83
wait et notify
HASSOUNI Larbi 84
Exécution conditionnelle
• Lorsqu’un programme est multi-tâche, la
situation suivante peut se rencontrer :
– Un thread t1 ne peut continuer son exécution
que si une condition est remplie
– Le fait que la condition soit remplie ou non
dépend d’un autre thread t2
• Par exemple, t1 veut utiliser le résultat d’un
calcul effectué par t2
HASSOUNI Larbi 85
Exécution conditionnelle (2)
• Une solution coûteuse serait que t1 teste la
condition à intervalles réguliers
• Les méthodes wait() et notify() de la
classe Object permettent de programmer
plus efficacement ce genre de situation
HASSOUNI Larbi 86
Schéma d’utilisation de wait-notify
• Cette utilisation demande un travail coopératif
entre les threads t1 et t2 :
1. Ils se mettent d’accord sur un objet commun
objet
2. Arrivé à l’endroit où il ne peut continuer que si la
condition est remplie, t1 se met en attente :
objet.wait();
3. Quand t2 a effectué le travail pour que la condition
soit remplie, il le notifie :
objet.notify();
ce qui débloque t1
HASSOUNI Larbi 87
Exemple d’utilisation de wait et notifyAll
HASSOUNI Larbi 88
class ThreadAjout extends Thread{
HASSOUNI Larbi 89
class ThreadPuise extends Thread{
HASSOUNI Larbi 90
import java.util.Scanner;
public class Synchro3{
public static void main (String args[]){
Reserve r = new Reserve () ;
ThreadAjout ta1 = new ThreadAjout (r, 100, 15) ;
ThreadAjout ta2 = new ThreadAjout (r, 50, 20) ;
ThreadPuise tp = new ThreadPuise (r, 300, 10) ;
System.out.println ("Suivi de stock --- Taper entree pour arreter ") ;
ta1.start () ; ta2.start () ; tp.start () ;
String s = new Scanner(System.in).nextLine();
ta1.interrupt () ; ta2.interrupt () ; tp.interrupt () ;
}
}
HASSOUNI Larbi 91
Besoin de synchronisation
• Le mécanisme d’attente-notification lié à un
objet met en jeu l’état interne de l’objet ;
pour éviter des accès concurrent à cet état
interne, une synchronisation est nécessaire
• Les appels:
-objet.wait()
-objet.notify()
-objet.notifyAll())
ne peuvent donc être effectués que dans du
code synchronisé sur objet
HASSOUNI Larbi 92
Méthode wait()
• public final void wait()
throws InterruptedException
• objet.wait()
– nécessite que le thread en cours possède le
moniteur de objet
– bloque le thread qui l’appelle, jusqu’à ce qu’un
autre thread appelle la méthode
objet.notify() ou objet.notifyAll()
– libère le moniteur de l’objet (l’opération « blocage
du thread – libération du moniteur » est atomique)
HASSOUNI Larbi 93
Méthode notifyAll()
HASSOUNI Larbi 94
Méthode notifyAll()
• Un seul des threads débloqués va récupérer le
moniteur ; on ne peut prévoir lequel
• Les autres devront attendre qu’il relâche le
moniteur pour être débloqués à tour de rôle,
mais ils ne sont plus bloqués par un wait
• En fait, souvent ils se bloqueront à nouveau
eux-mêmes (s’ils sont dans une boucle while
avec wait)
HASSOUNI Larbi 95
Méthode notify()
• objet.notify()
– idem notifyAll() mais
– ne débloque qu’un seul thread
• On ne peut prévoir quel sera le thread
débloqué et, le plus souvent, il vaut donc mieux
utiliser notifyAll()
HASSOUNI Larbi 96
Déblocage des threads
HASSOUNI Larbi 97
notify perdus
HASSOUNI Larbi 98
Exemple avec wait-notify
• Les instances d’une classe Depot contiennent
des jetons
• Ces jetons sont
– déposés par un producteur
– consommés par des consommateurs
• Les producteurs et consommateurs sont des
threads
HASSOUNI Larbi 99
Exemple avec wait-notify
public class Depot {
private int nbJetons = 0;
public synchronized void donneJeton() {
try {
while (nbJetons == 0) {
wait();
}
nbJetons--;
}
catch (InterruptedException e) {}
}
The addShutdownHook() method of Runtime class is used to register the thread with the
Virtual Machine.
Syntax: public void addShutdownHook(Runnable r){}
The object of Runtime class can be obtained by calling the static factory method
getRuntime(). For example:
Runtime r = Runtime.getRuntime();
Factory method
The method that returns the instance of a class is known as
factory method.
switch(cas){
case 0 : int i = 10 / 0; break;
case 1 : Object str = "toto"; double d = (double) str;
break;
default :
System.out.println(getName() + ": aucune erreur...");
break;
} } }}
Bien à vous