Vous êtes sur la page 1sur 33

FORMATION  JAVA

Partie VII:  Les threads
Dr. GOORE BI Tra / goore@inphb.edu.ci / (+225) 07 90 39 73
Gestion des Threads

 Threads ou activités ou processus légers
 Unités d'exécution autonomes qui peuvent effectuer 
des tâches, en parallèle avec d'autres threads. 
 Plusieurs threads peuvent être associés à un 
« processus lourd »
 Les threads coopèrent entre eux en échangeant des 
valeurs par la mémoire commune du processus lourd. 
 Cependant chaque thread peut disposer de son 
propre environnement ou contexte d'exécution

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 2
Gestion des Threads

 Etats d’un Thread

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 3
Gestion des Threads

 La classe Thread
 Les constructers de la classe Thread
public Thread (); 
public Thread (String nom); 
public Thread (Runnable code, String nom); 
public Thread (Runnable code)
Thread(ThreadGroup groupe, Runnable code , String nom)
Thread(ThreadGroup groupe, Runnable code)
Thread(ThreadGroup groupe, String nom)

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 4
Gestion des Threads

 La classe Thread
 Quelques méthodes
• public void start()
– permet de démarrer un thread dont le code à exécuter est la méthode run.
• static Thread currentThread()
– permet d'obtenir l'activité appelante ; 
• static void yield()
– laisse une chance aux autres activités de s'exécuter ; 
• public void suspend() // n’est plus utilisé
– permet d'arrêter temporairement un thread en cours d'exécution.
• static void sleep(long millisec) throws InterruptedException
– suspend l'exécution de l'activité appelante pendant la durée indiquée ou 
jusqu'à ce que l'activité soit interrompue
• public void join() throws InterruptedException
– attend que l'activité soit terminée ; 

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 5
Gestion des Threads

 La classe Thread
 Quelques méthodes
• public void resume()
– permet de relancer l'exécution d'un thread, au préalable mis en pause via 
suspend. 
• public void stop() // n’est plus utilisé
– permet de stopper, de manière définitive, l'exécution du thread. 
• String getName()
– retourne le nom du Thread. Cette méthode est de la classe Object
• void SetName(String nom)
• redéfinit le nom
• public void join(long millisec) throws InterruptedException
– attend que l'activité soit terminée ou que le délai de garde soit écoulé.
• Thread.State getState()
– Récupère l'état de ce thread ; peut être l'une des constantes NEW, RUNNABLE, 
BLOCKED, WAITING, TIMED_WAITING ou TERMINATED.

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 6
Gestion des Threads

 La classe Thread
 Quelques méthodes
• boolean isAlive()
– Renvoie true si le thread est démarré et n'est pas encore terminé.
• void interrupt()
– Envoie une demande d'interruption à un thread. L'indication 
« interrompu » du thread est mise à true.
– Si le thread est actuellement bloqué (sleep() ou à wait()), une 
InterruptedException est déclenchée
• boolean isinterruped()
– Pour savoir si le thread a été interrompu. Indicateur « interrompu » 
non modifié. 
• static boolean interrupted()
– Idem, mais indicateur « interrompu » est mis à faux.

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 7
Gestion des Threads

 La classe Thread
 La méthode interrupt()
• Lorsque cette méthode est appelée sur un thread 
actuellement bloqué, l'appel bloquant (sleep() ou wait()) est 
terminé par une InterruptedException.

• Remarque
• Ce mécanisme ne permet pas d’interrompre une entrée/sortie 
bloquante comme une lecture en attente de donnée
• l’indicateur est positionné, mais aucune exception n’est levée et 
l’activité reste bloquée.

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 8
Gestion des Threads

 Création et démarrage d’un Thread
 Deux techniques pour créer un thread
• Hériter de la classe java.lang.Thread
– Chaque thread a ses données qui lui sont propres.
– Elle consiste à redéfinir la méthode run() de la classe Thread

• Implémenter l'interface java.lang.Runnable
– Les données de la classe sont partagées par tous les threads.
– Elle consiste à créer une classe qui implémente l'interface 
« runnable ».
– Cette interface déclare seulement une méthode : run(). 

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 9
Gestion des Threads

 Création par héritage de la classe Thread
 Déclaration de la classe
class MonThread extends Thread {
MonThread () {
// code du constructeur
}
public void run () {
// code exécuté par le thread
}
}
 Création d’un instance de Thread
MonThread p = new MonThread();
p.start();
• L'appel de la méthode start () passe le thread à l'état « prêt », ce 
qui lui permet de démarrer dès que possible

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 10
Gestion des Threads

 Création par implémentation de l’interface runnable
 Déclaration de la classe
class MonCode implements Runnable {
MonCode() {
// code du constructeur
}
public void run() {
// code à exécuter dans le thread
}
}
 Création d’un instance de Thread
MonCode code = new Moncode ();
Thread T = Thread(code);
T.start();

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 11
Gestion des Threads

 Création par implémentation de l’interface runnable
 Création d’une instance de classe en utilisant les classes 
anonymes
Thread T = new Thread (new Runnable() {
Void run() {

}
})

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 12
Gestion des Threads
 Exemple
Le programme crée 4 processus qui s’exécutent en parallèle. La tâche
réalisée par chaque processus est d’afficher simplement son nom.

class Processus extends Thread {
public Processus(String nom) {
super(nom);
}
public void run() {
for (int i=0; i<10; i++) {
try {
sleep(1000);
} catch (Exception e) {};
//effectue la tâche prévue
System.out.println ("Je suis le processus "+getName());
}
}
};

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 13
Gestion des Threads

 Exemple (suite)
class TestThread {
public static void main(String args[]) {
Processus P1=new Processus ("processus 1");
Processus P2=new Processus ("processus 2");
Processus P3=new Processus ("processus 3");
Processus P4=new Processus ("processus 4");
P1.start();
P2.start();
P3.start();
P4.start();  
}
}
}
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 14
Synchronisation des processus

 L’exclusion mutuelle
 Il existe un espace de travail commun pour les threads.
 Il n’y a pas de « mémoire privée » pour chaque thread. 
 L’inconvénient est l’accès simultané à une même ressource 
de l’espace d’adressage. 
 Il faut donc garantir l’accès exclusif à un objet pendant 
l’exécution d’une ou plusieurs instructions. 
 A défaut, lors de l’exécution d’une méthode par un thread, 
l’état de l’objet peut être temporairement être corrompu.

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 15
Synchronisation des processus

 Section critique
 Partie d’un programme qui contient une ressource 
partagée par plusieurs processus.
 Mécanisme de synchronisation offert par java
 Les verrous
 Les files de blocage

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 16
Synchronisation des processus

 La clause « synchronized »
 Elle part du principe que chaque objet Java possède un verrou intrinsèque.
 Moyen de protection d’une méthode
public synchronized « type» NomMéthode() {
// section principale
}
Objet de condition de la clause « synchronized »
 Une seule condition
 Les méthodes (applicables à tout objet)
• wait() throws llegalMonitorStateException
– Exeception si le thread courant n'est pas propriétaire du verrou d'objet.
• void wait(long millisecondes, int nanosecondes)
– Amène un thread à patienter jusqu'à ce qu'il soit notifié ou jusqu'à ce que le délai spécifié se soit 
écoulé.
• notifyAll() 
• notify()
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 17
Synchronisation des processus

 Exemple: schéma du producteur consommateur
 Problème
Le programme réalise l’accès synchronisé à une pile qui
constitue une ressource partagée par la classe des
producteurs (ceux qui empilent) et la classe des
consommateurs (ceux qui dépilent).

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 18
Synchronisation des processus
 Exemple: schéma du producteur consommateur
 La classe Pile
import java.util.*;
public class Pile {
private int tab [];
private int taille, sommet;

public Pile() {
this (5);
}
public Pile(int taille) {
this.taille = taille; 
this.sommet = 0;
this.tab = new int[taille];
}
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 19
Synchronisation des processus

 Exemple: schéma du producteur consommateur
 La classe Pile (suite)
//Renvoie true si la pile est vide 
public boolean estVide() { return sommet == 0; }
// Renvoie true si la pile est pleine 
public boolean estPlein() { return sommet == taille; }
// Méthode synchronisée pour dépiler un élément
public synchronized int depiler () {
try { 
while (estVide()) {
System.out.println("Mise en attente du demandeur");
wait();
}
} catch(Exception e) {
e.printStackTrace();
}
int element = tab[‐‐sommet];
notifyAll();
return element;
}

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 20
Synchronisation des processus

 Exemple: schéma du producteur consommateur
 La classe Pile (suite)
// Méthode synchronisée pour empiler un élément
public synchronized void empiler(int element) {
try { 
while (estPlein()) {
System.out.println("Mise en attente du demande de empiler");
wait();
}
} catch(Exception e) {
e.printStackTrace();
}

tab[sommet++] = element;
notifyAll();
}
};
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 21
Synchronisation des processus

 Exemple: schéma du producteur consommateur
 La classe Producteur
class CodeProducteur implements Runnable {
static Pile pile;
int element = 0;
String nom;
Random alea = new Random();
public CodeProducteur (String nom) {
this.nom = nom;
}

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 22
Synchronisation des processus

public void run() {
while (true) {
try {
Thread.sleep(alea.nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println (nom + " empile " + element);
pile.empiler(++element);
}
}
};
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 23
Synchronisation des processus

 Exemple: schéma du producteur consommateur
 La classe Consommateur 

class CodeConsommateur implements Runnable {
static Pile pile;
String nom;
Random alea = new Random();
public CodeConsommateur (String nom) {
this.nom=nom;
}

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 24
Synchronisation des processus

public void run() {
while (true) {
try {
Thread.sleep(alea.nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println (nom + " depile " + pile.depiler());
}
}
}
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 25
Synchronisation des processus

 Exemple: schéma du producteur consommateur
 Test final 
class testPile {
static public void main (String args[]) {
// Démarrage de deux Producteurs

CodeProducteur.pile = new Pile(5);
CodeConsommateur.pile = CodeProducteur.pile;    

CodeProducteur codeproducteur1 = new CodeProducteur
("Producteur1");
CodeProducteur codeproducteur2 = new CodeProducteur
("Producteur2");
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 26
Synchronisation des processus

Thread producteur1 = new Thread(codeproducteur1);
producteur1.start();
Thread producteur2 = new Thread(codeproducteur2);
producteur2.start();
// Démarrage de deux consommateur
CodeConsommateur consommateur1 = new  CodeConsommateur
(« consommateur1");
CodeConsommateur consommateur2 = new  CodeConsommateur
("Consommateur2");

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 27
Synchronisation des processus

Thread consommateur1 = new Thread(Codeconsommateur1);
consommateur1.start();
Thread consommateur2 = new Thread(Codeconsommateur2);
consommateur2.start();
while (true) { // Mise en veille du thread principal
try { 
Thread.sleep (10000L);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 28
Exécution de tâche longue

 Les taches longues
 Tout traitement long effectué par le thread principal peut
• Figer l’interface graphique qui répond mal
• Bloquer l’interface qui ne répond pas du tout  aux actions de 
l’utilisateur
 Exemple Traitement long souvent dans les «Listener»
– accès à une base de données, 
– Calculs long
– dessins complexes
– Etc.
 Il faut donc éviter d'exécuter des opérations longues dans 
les gestionnaires d'événement.
 Les traitements longs doivent donc être traités dans des 
thread à part.
Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 29
Exécution de tâche longue

 Deux règles pour utiliser threads avec Swing
 Si une action est trop longue, elle doit être exécutée  dans 
un thread séparé et jamais dans le thread de répartition 
des événements (thread principal).
 Règle du thread unique: Les composants Swing ne doivent 
pas être modifiés dans un thread autre que le thread de 
répartition des événements.
 Problème: comment exécuter une tâche longue qui 
modifie un composant ?
 Utiliser les méthodes invokeLater(Runnable) et 
invokeAndAwait(Runnable) 

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 30
Exécution de tâche longue
 Exemple 1
public void actionPerformed(ActionEvent e) { 
new Thread(new Runnable() { 
public void run() { 
String text = readHugeFile(); 
textArea.setText(text); } }).start(); 
}
 Exemple 2
public void actionPerformed(ActionEvent e) { 
new Thread(new Runnable() { 
public void run() { 
final String text = readHugeFile(); 
SwingUtilities.invokeLater(new Runnable() { 
public void run() {
textArea.setText(text);
} } } }).start(); 
}

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 31
Exécution de tâche longue

 La classe EventQueue
 static void invokeLater(Runnable tâche)
• Amène la méthode run() de l'objet tâche à s'exécuter dans 
le thread de répartition des événements
 static void invokeAndWait(Runnable tâche)
• Idem , mais  bloquante jusqu'à ce que la méthode run() se 
termine.
 static boolean isDispatchThread()
• Renvoie true si le thread exécutant cette méthode est le 
thread de répartition des événements.

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 32
Exécution de tâche longue

 Quelques exceptions :
 Ajout et suppression des écouteurs d'événements de 
n'importe
 Un petit nombre de méthodes Swing sont compatibles 
avec les threads. 
• "This method is thread safe (compatible), although most Swing 
methods are not"
• JTextComponent.setText()
• JTextArea.insert()
• JTextArea.append()
• JTextArea.replaceRange()
• JComponent.repaint()
• JComponent.revalidate()

Dr. GOORE BI Tra                                         (+225) 07 90 39 73                               goore@inphb.edu.ci 33

Vous aimerez peut-être aussi