Vous êtes sur la page 1sur 33

Chapitre

Java Avancé

2
Thread

1
2014 - 2015 © Yousri Kessentini
Thread
les threads sont des processus légers qui s’exécutent en parallèle
mais partagent les données.
Sur un OS évolué, exécution concurrente possible des
processus avec “temps partagé” géré par un scheduler
Java Avancé

Fenêtres Multiples
Calcul en tâche de fond
Animation
Producteur/consommateur
Serveur avec plusieurs clients (web ou autres)
Recherche (base de données, web)

2
2014 - 2015 © Yousri Kessentini
Thread en Java
Java propose deux solutions :
Objet héritant de la classe java.lang.Thread.
Public class Proc1 extends java.lang.Thread{
Public Proc1(){...} //Le constructeur
Java Avancé

...
Public void run(){
... //Ici ce que fait le processus (boucle infinie)
}}
Proc1 p1=new Proc1(); //Création du processus
p1.start(); //Démarre le processus et exécute p1.run()

3
2014 - 2015 © Yousri Kessentini
Thread en Java
Objet implémentant l’interface java.lang.Runnable

Public class Proc2 implements java.lang.Runnable{


Public Proc2(){...} //Le constructeur
Java Avancé

...
Public void run(){
... //Ici ce que fait le processus (boucle infinie)
}}
Proc2 p=new Proc2();
Thread p2= new Thread (p);
p2.start(); //Démarre le processus et exécute p.run()

4
2014 - 2015 © Yousri Kessentini
Que choisir ?
Hériter de Thread
Pour paralléliser une classe qui n’hérite pas déjà d’une autre
classe (héritage simple) ;

Implémenter Runnable
Java Avancé

Lorsqu’une super-classe est imposée ;

Exemple: Cas des applets


public class MyThreadApplet
extends Applet implements Runnable { . . . }

5
2014 - 2015 © Yousri Kessentini
Exemple
class TPrint1 extends Thread { public class TestThread1 {
String txt; static public void main(String
int attente; args[]) {
public TPrint1(String t, int p) { TPrint1 a = new TPrint1("A",
txt = t; 100);
attente = p; TPrint1 b = new TPrint1("B",
Java Avancé

200);
}
a.start();
public void run() {
b.start();
for (int i=0; i<8; i++) {
}
System.out.print(txt+i+" ");
}
try {
sleep(attente);
}
Résultat de l'exécution :
catch(InterruptedException e)
{};
} A0 B0 A1 B1 A2 A3 B2 A4
} A5 B3 A6 A7 B4 B5 B6 B7
}
6
2014 - 2015 © Yousri Kessentini
Exemple
class TPrint2 implements Runnable { public class TestThread2 {
String txt; static public void main(String args[]) {
int attente; TPrint2 a = new TPrint2("A", 100);
public TPrint2(String t, int p) { TPrint2 b = new TPrint2("B", 200);
txt = t; new Thread(a).start();
attente = p; new Thread(b).start();
Java Avancé

} }
public void run() { }
for (int i=0; i<8; i++) {
System.out.print(txt+i+" ");
try {
Thread.currentThread().sleep(
attente);
} Résultat de l'exécution :
catch(InterruptedException e) {};
}
}
A0 B0 A1 B1 A2 A3 B2 A4
} A5 B3 A6 A7 B4 B5 B6 B7

7
2014 - 2015 © Yousri Kessentini
Java Avancé
Méthodes de la classe Thread

8
2014 - 2015 © Yousri Kessentini
Java Avancé
Gestion des Threads

9
2014 - 2015 © Yousri Kessentini
Ordonnancement du Thread
En général, le thread exécutable avec la plus haute priorité
est activé (running)
Java est priority-preemptive
Si un thread de haute-priorité se réveille, et un thread
de basse priorité s’exécute
Java Avancé

Alors le thread de haute priorité s’exécute


immédiatement
Permet l’exécution à la demande
utilisation efficace du CPU

10
2014 - 2015 © Yousri Kessentini
Synchronisation des threads

start()
Thread Thread
Java Avancé

extends Thread/ implement Runnable extends Thread/ implement Runnable

méthodeA() méthodeA()

méthodeB() méthodeB()

run() run() Attributes

Attention ! 11
2014 - 2015 © Yousri Kessentini
Exemple

thread 1 thread 2
Java Avancé

x = attribute
attribute = attribute + 1
x = x+1

attribute = x
incrément perdu

12
2014 - 2015 © Yousri Kessentini
Solution 1

thread 1
class Xxx { thread 2
Object o = new Object();
Java Avancé

public void methodeB() {


synchronized (o) { // one thread at a time
attribute = attribute + 1;
}
}

13
2014 - 2015 © Yousri Kessentini
Solution 2

thread 1
class Xxx { thread 2
Java Avancé

public synchronized void methodeB() {


attribute = attribute + 1;
}
}
// l’objet unique de protection est l’objet qui contient
methodeB() . Il doit être instancié. Pas d’accès static.

14
2014 - 2015 © Yousri Kessentini
Exemple
class Compte {
private int solde;
synchronized public void depot(int valeur)
{
int nouveauSolde;
Java Avancé

nouveauSolde = solde + valeur;


solde = nouveauSolde ;
}
synchronized public void retirer(int valeur)
{
int nouveauSolde ;
nouveauSolde = solde - valeur;
solde = nouveauSolde ;
}
}
15
2014 - 2015 © Yousri Kessentini
Attente explicite : wait() - notify()
Producteur/Consommateur
Une mémoire tampon est alimentée par un producteur
d’objets et utilisée par un consommateur
On synchronise l’accès à cette mémoire (production et
consommation non simultanées)
Java Avancé

Si le producteur doit déposer un objet alors qu’il en existe


déjà un dans le tampon => blocage ;
Même problème pour un consommateur qui attend le dépôt.

16
2014 - 2015 © Yousri Kessentini
Attente explicite : wait() - notify()
Relachement d’exclusion
L’attente du consommateur ou du producteur se fait par
wait() (exception InterruptedException) qui relâche
l’exclusion ;
Un processus sort de son endormissement (attente) quand
Java Avancé

un autre processus exécute notify() ou notifyAll() (relance


tous les processus en attente) ;

17
2014 - 2015 © Yousri Kessentini
Wait et Notify: Code
consommateur:
synchronized (lock) {
while (!resourceAvailable()) {
lock.wait();
Java Avancé

}
consumeResource();
}
Producteur:
produceResource();
synchronized (lock) {
lock.notifyAll();
}
18
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

19
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

20
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

21
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

22
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

23
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

24
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

25
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupèrer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

26
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupérer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

27
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupérer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

28
2014 - 2015 © Yousri Kessentini
Séquence du Wait/Notify

Objet Lock
1. synchronized(lock){ 3. produceResource()
4. synchronized(lock) {
Java Avancé

2. lock.wait();
5. lock.notify();
9. consumeResource();
10. } 6.}
7. Récupérer le lock
8. Retour du wait()
Consommateur Producteur
Thread Thread

29
2014 - 2015 © Yousri Kessentini
Exercice
Un producteur produit des objets (int) et les place dans une file
d’attente
Un consommateur prend ce qu’il trouve dans la file

La file d’attente
Java Avancé

on produit et consomme des entiers (int)


la file est limitée à un entier

Définir les classes Produit, Producteur, Consommateur

30
2014 - 2015 © Yousri Kessentini
Solution: Produit

class Produit {
int contenu;
boolean vide;
Java Avancé

Produit() {vide = true;}


void ajoute(int x) {contenu = x; vide = false;}
int retire() {vide = true; return contenu;}
boolean estVide() {return vide;}
}

31
2014 - 2015 © Yousri Kessentini
Solution : Producteur
class Producteur extends Thread {
Produit produit;
Producteur(Produit p) {this.produit = p;}
public void run() {
int ip;
while (true) {
// dort un moment
Java Avancé

try {sleep((int)(Math.random() * 1000));}


catch (InterruptedException e) {};
synchronized (produit) {
if (!produit.estVide()) {
try produit.wait();
catch (InterruptedException e);
}
ip = (int)(Math.random() * 1000);
produit.ajoute(ip);
// signale qu’il y a qqch à prendre
produit.notify();
}
}}}
32
2014 - 2015 © Yousri Kessentini
Solution : Consommateur
class Consommateur extends Thread {
Produit produit;
Consommateur (Produit p) {this.produit = p;}
public void run() {
int jp;
while (true) {
Java Avancé

try {sleep((int)(Math.random() * 1000));}


catch (InterruptedException e) {};
synchronized (produit) {
if (produit.estVide()) {
try produit.wait();
catch (InterruptedException e);
}
jp = produit.retire();
produit.notify();
}
}}}

33
2014 - 2015 © Yousri Kessentini

Vous aimerez peut-être aussi