Académique Documents
Professionnel Documents
Culture Documents
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