Thread

Transcription

Thread
Les tâches et la synchronisation
en langage Java
Les threads, les verrous, les sémaphores
et les moniteurs en Java
D’après les cours de D. Genthial et B. Caylux
Langage Java – Threads et synchronisation
1
Généralités
z
E java
En
j
une tâ
tâche
h estt un processus lé
léger :
Î
Î
z
En Java, un processus léger peut être créé
par :
1.
2.
z
il p
partage
g l’espace
p
mémoire de l’application
pp
qui
q l’a
lancé.
il possède sa propre pile d
d’exécution.
exécution.
dérivation de la classe Thread.
implémentation de l’interface Runnable.
D
Documentation
t ti officielle
ffi i ll d
de S
Sun :
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html
Langage Java – Threads et synchronisation
2
Th d
Thread
z
z
z
Un thread est constitué essentiellement d’une
méthode run ()
Cette méthode est appelée par la méthode
start()
Un Thread vit jusqu’à la fin de l’exécution de sa
méthode run.
Î Un
thread p
peut être endormi p
par sleep(nb
p( de ms))
Î Un thread peut passer son tour par yield()
Î Un thread peut se mettre en attente par wait()
Langage Java – Threads et synchronisation
3
Dérivation de Thread
Création d’une classe
class MonThread extends Thread{
MonThread(...){
Constructeur
}
public void run(){
...
Algorithme décrivant
le comportement du thread
}
...
}
Création et lancement du thread
MonThread mt = new MonThread ();
mt start() // exécute la méthode run de mt
mt.start()
Langage Java – Threads et synchronisation
4
4
Création de Thread par spécialisation
de la classe Thread
z
E
Exemple
l
class MaPremiereTache extends Thread {
public MaPremiereTache() {
super();
}
public void run() {
System.out.println(“Bonjour le monde !”);
}
}
...
MaPremiereTache t = new MaPremiereTache ();
t.start(); // exécute la méthode run de t
Langage Java – Threads et synchronisation
5
Création de Thread par implémentation
de l’interface Runnable
z
Seule façon possible si la classe X dérive déjà d
d’une
une
autre classe.
class X extends . . . implements Runnable{
Cible du Thread qui
contient la définition
de la méthode run()
qui sera exécutée par
start()
()
public void run(){
. . .
}
. . .
}
X x = new X();
Thread leThread = new Thread(x);
leThread.start(); // exécute le run de la cible
Langage Java – Threads et synchronisation
6
6
Création de Thread p
par implémentation
p
de l’interface Runnable
L’interface
L
interface Runnable
public abstract interface
Runnable {
public abstract void run();
}
Utilisation
public
p
blic class MaPremiereTache implements Runnable
R nnable {
...
public void run() {
System out println(“Bonjour
System.out.println(
Bonjour le monde !”);
! );
}
}
Langage Java – Threads et synchronisation
7
Création de Thread p
par implémentation
p
de l’interface Runnable
L’interface
L
interface Runnable
public abstract interface
Runnable {
public abstract void run();
p
}
Autre implémentation
Cible d
Cibl
du Thread
Th d quii
class X extends . . . implements Runnable{ doit contenir la
définition de la
Thread leThread = new Thread(this);
méthode run()
public void run(){
...
}
. . .
leThread.start(); // exécute la méthode run de la cible
}
Langage Java – Threads et synchronisation
8
Création de Thread p
par implémentation
p
de l’interface Runnable
z
C é ti d’
Création
d’une tâ
tâche
h à partir
ti d’
d’un objet
bj t R
Runnable
bl
Runnable maTache = new MaPremiereTache(...);
Thread leThread = new Thread(maTache);
leThread.start();
// démarrage
z
ou simplement (tâche anonyme)
Runnable maTache = new MaPremiereTache(...);
new Thread(maTache).start();
z
ou encore...
MaPremiereTache maTache = new MaPremiereTache(...);
new Thread(maTache).start();
Langage Java – Threads et synchronisation
9
Méth d statiques
Méthodes
t ti
z
Ell agissent
Elles
i
sur lle thread
h d appelant
l
Î Thread.sleep(long
p( g
ms))
bloque le thread appelant pour la durée
spécifiée;
Î Thread.yield()
Le thread appelant relâche le processeur au
profit d’un thread de même priorité;
Î Thread.currentThread()
Th d
tTh d()
retourne une référence sur le thread appelant;
Langage Java – Threads et synchronisation
10
Méth d d’i
Méthodes
d’instances
t
MonThread
M
Th d p = new MonThread
M Th d ()
();
z p.start()
démarre le thread p;
z p.isAlive() détermine si p est vivant (ou terminé);
z p
p.join()
j ()
bloque
q l’appelant
pp
jjusqu’à
q
ce q
que p soit terminé;;
z p.setDaemon()
attache l’attribut « daemon » à p;
z p.setPriority(int
p setPriority(int pr)
assigne la priorité pr à p;
z p.getPriority()
retourne la priorité de p;
z …(beaucoup
(b
d’
d’autres))
Langage Java – Threads et synchronisation
11
Le cycle
y
de vie d’un thread
Création :
new …
objet
créé
TERMINATED
NEW
start()
RUNNABLE
yield()
y
()
notify() ou notifyAll()
interrupt()
bloqué
p
du temps
p
expiration
BLOCKED
Langage Java – Threads et synchronisation
fin de la
méthode run
En cours
d’exécution
d
exécution
exécutable
verrou alloué
Mort
Demande
de verrou
12
wait()
join()
sleep()
En attente
WAITING
TIMED_WAITING
12
A êt d’une
Arrêt
d’
tâ
tâche
h
z
Un Thread dans l’état
l état bloqué ou en attente peut être
arrêté par interrupt()
class MonThread extends Thread{
. . .
public void run(){
try{
while (true){
. . .
sleep(100);
}
}catch(InterruptedException ie){
. . .
}
}
MonThread t = new MonThread ();
. . .
t.start();
}
. . .
t.interrupt();
Langage Java – Threads et synchronisation
13
A êt d’une
Arrêt
d’
tâ
tâche
h
z
L itération peut être contrôlée par un booléen et
L’itération
arrêtée par une fonction qui rend vrai le booléen.
class MonThread extends Thread{
boolean arret = false;
public void run(){
try{
while(!arret){
. . .
}
}catch(InterruptedException
. . .
}
}
public void stop (){
arret = true;
}
. . .
}
Langage Java – Threads et synchronisation
ie){
MonThread t = new MonThread ();
t.start();
. . .
t.stop();
14
Arrêt d’une tâche
public void run() {
try {
// Corps de la tâche
...
} catch (InterruptedException e) {
// Terminer la tâche
...
return;
} fi
finally
ll {
// Code exécuté avant la fin de la tâche, quelle que soit
// la cause qui l’a arrêtée (fin normale ou exception
// ou erreur)
...
}
}
Langage Java – Threads et synchronisation
15
J i t
Jointure
d
de th
threads
d
z
Un thread peut avoir à attendre la fin d’un
d un ou
plusieurs threads pour démarrer : join()
class MonThread extends Thread{
Thread precedent;
public MonThread( Thread p){
précédent
é éd t = p;
}
public
p
blic void
oid run(){
try{
precedent.join(); // le thread reste bloqué tant que
// precedent n
n’est
est pas terminé
. . .
}catch(InterruptedException ie){
. . .
}
}
}
Langage Java – Threads et synchronisation
16
P i ité d
Priorité
des th
threads
d
z
Les Threads ont une priorité qui va de
Î
Î
Î
z
z
z
z
Thread.MIN_PRIORITY (1)
Thread NORM PRIORITY (5)
Thread.NORM_PRIORITY
Thread.MAX_PRIORITY (10)
int getPriority() ;
void setPriority(int p) ;
void
id setDaemon(boolean
D
(b l
on)) permet de
d rendre
d un
thread démon : thread qui s’exécute en tâche de
f d
fond.
Un programme Java se termine lorsque tous les threads user
sont terminés (les threads daemon n’ont
n ont pas besoin d’être
d être
terminés).
Langage Java – Threads et synchronisation
17
Th d d
Threads
de lla JVM
z
En plus
E
l d
des th
threads
d d
du programme JJava,
une machine virtuelle Java exécute des
threads dédiés à des tâches de gestion :
Î
Î
Î
Î
thread oisif (priorité 0): exécuté si aucun autre thread ne
s’exécute;
ramasse-miettes (garbage collector, priorité 1): récupère les
objets qui ne sont plus accessibles (référencés)
(référencés). Ce thread ne
s’exécute que lorsqu’aucun autre thread (à part le thread oisif)
ne s’exécute;
gestionnaire
ti
i d’horloge:
d’h l
gère
è tous lles é
événements
é
iinternes lié
liés
au temps;
thread de finalisation: appelle la méthode finalize( ) des objets
récupérés par le ramasse-miettes.
Langage Java – Threads et synchronisation
18
Ordonnancement des tâches : la théorie
z
Les threads exécutable se trouvent dans les queues de différentes
priorités, gérées par le run-time de Java:
Î
Î
Î
z
z
si plus d’un thread exécutable, Java choisit le thread de plus haute
priorité;
si plus d’un thread de plus haute priorité, Java choisit un thread
arbitrairement;
un thread en cours d’exécution perd le CPU au profit d’un
d un thread de
plus haute priorité qui devient exécutable;
par défaut, un thread a la même priorité que le thread qui l’a créé;
la priorité peut être changée en appelant Thread.setPriority().
Langage Java – Threads et synchronisation
19
Ordonnancement des tâches : la réalité
z
La politique
L
liti
d’allocation
d’ ll
ti d
du processeur aux th
threads
d
de même priorité n’est pas fixée par le langage.
Î
z
Ell peutt êt
Elle
être avec ou sans préemption!!!
é
ti !!!
Pas de traitement cohérent de la priorité:
exemple: la priorité n’est pas utilisée par la méthode notify()
pour choisir le processus à débloquer;
z
La spécification
f
du langage n’exige pas que les
priorités soient prises en compte par le runtime.
Langage Java – Threads et synchronisation
20
S
Synchronisation
h
i ti
z
z
Comment empêcher plusieurs threads
d’accéder en même temps à un objet ?
Chaq e objet Ja
Chaque
Java
a possède un
n verrou
erro
d’exclusion mutuelle.
Î
S
Synchronisation
h
i ti
d’un
d’
bloc
bl d’instructions
d’i t
ti
synchronized (objet){
. . . // Aucun autre thread ne
. . . // peut accéder à objet
}
Î
Synchronisation d
d’une
une méthode
synchronized void f(){
. . . // Aucun autre thread ne
. . . // peut
t accéder
éd
à l’
l’objet
bj t
. . . // pour lequel est appelé la méthode f
}
Langage Java – Threads et synchronisation
21
les verrous (rappel)
Type verrou = structure
ouvert : booléen;
attente : liste de tâches;
fin verrou;;
procédure verrouiller (modifié v : verrou);
début
si v.ouvert alors
v.ouvert Å faux
sinon
Ajouter la tâche dans la liste v.attente
dormir
finsi;
fin verrouiller;
Langage Java – Threads et synchronisation
procédure init_verrou
init verrou (modifié v : verrou);
début
v.ouvert Å vrai;
v.attente Å vide;;
fin init_verrou;
procédure déverrouiller (modifié v : verrou);
début
si v.attente ≠ vide alors
Sortir la première tâche de v.attente,
La réveiller
sinon
v.ouvert Å vrai
fi i
finsi;
fin déverrouiller;
22
Exemple : voie unique (rappel)
Tâche
Tâ
h Train
T i (modifié
( difié voie
i : verrou);
)
début
rouler;
verrouiller(voie);
Passer;
(
);
déverrouiller(voie);
rouler;
rouler;
synchronized (voie){
passer;
fin TrainGauche;
}
rouler;
Langage Java – Threads et synchronisation
23
E
Exemple
l d
de bl
bloc synchronized
h i d
Comment garantir une exécution atomique des commandes
suivantes ?
System.out.print (new Date ( )) ;
System.out.print (" : ") ;
System.out.println (...) ;
(les méthodes print et println de la classe Printstream sont
synchronisées )
Synchronized (System.out){
System.out.print (new Date ( ) ) ;
System.out.print (" : ") ;
System.out.println (...) ;
}
lorsqu’une méthode synchronized est appelée, le thread
appelant
pp
doit obtenir le verrou associé à l’objet
j
Langage Java – Threads et synchronisation
24
S
Synchronisation
h i ti
z
La synchronisation par verrou peut
provoquer des « interblocages » (dead
l k ) amenantt l’l’arrêt
locks)
êt défi
définitif
itif d
de un ou
plusieurs threads.
class MonThread1 extends
Th
Thread{
d{
public void run(){
synchronized(a){
. . .
synchonized(b){
. . .
}
}
}
}
Langage Java – Threads et synchronisation
class MonThread2 extends
Th
Thread{
d{
public void run(){
synchronized(b){
. . .
synchonized(a){
. . .
}
}
}
}
25
L verrous JJava : utilisation
Les
tili ti (1)
z
Synchronisation (verrouillage) sur un objet
public class Compte {
private double xSolde;
public Compte(double DépôtInitial) {
xSolde = DépôtInitial;
}
public synchronized double solde() {
etu
xSolde;
So de;
return
}
public synchronized void dépôt(double montant) {
xSolde
S ld = xSolde
S ld + montant;
t t
}
}
Î Solde et Dépôt sont exécutées en exclusion mutuelle sur un
objet donné (xSolde)
Langage Java – Threads et synchronisation
26
L verrous JJava : utilisation
Les
tili ti (2)
public class Chèques
implements Runnable {
public class Liquide
implements Runnable {
private Compte xCompte;
private Compte xCompte;
public Chèques(Compte c) {
xCompte = c;
}
public Liquide(Compte c) {
xCompte = c;
}
public void run() {
double montant;
// Lecture du montant
. . .
xCompte.dépôt(montant);
}
public void run() {
double montant;
// Lecture du montant
. . .
xCompte.dépôt(montant);
}
}
Langage Java – Threads et synchronisation
}
27
L verrous JJava : utilisation
Les
tili ti (3)
public class Banque {
public static void main(String [] arg) {
Compte monCompte = new Compte(2000.00);
Chèques c = new Chèques(monCompte);
Liquide
q
l = new Liquide(monCompte);
q
(
p )
new Thread(c).start();
new Thread(l).start();
}
}
Langage Java – Threads et synchronisation
28
S
Synchronisation
h i ti
z
Bl
Blocage
d’une
d’
tâche
tâ h
void wait();
Î
z
sur un objet quelconque
Réveil d’une
d une tâche
void notify();
Î
z
sur l’objet
l objet cause du blocage
Réveil
é e de toutes les
es tâc
tâches
es
void notifyAll();
Î
sur l’objet cause du blocage
Langage Java – Threads et synchronisation
29
S
Synchronisation
h i ti
La méthode wait() est définie dans la classe Object.
Object
z On ne peut utiliser cette méthode que dans un code synchronisé.
z Elle provoque ll'attente
attente du thread en cours d
d'exécution.
exécution.
z Elle doit être invoquée sur l'instance verrouillée.
synchronized(unObjet){
…
try{
unObjet.wait(); // unObjet bloque l’exécution du thread
}catch(InerruptedException ie){
…
}
z
Pendant
P
d t que le
l thread
th d attend,
tt d le
l verrou sur unObjet
Obj t estt relaché.
l hé
Î wait(long ms) attend au maximum ms millisecondes
Î wait(long
ait(long ms,
ms int ns) attend au
a maximum
ma im m ms millisecondes
+ ns nanosecondes
Langage Java – Threads et synchronisation
30
Synchronisation
z
L méthode
La
éth d notify()
tif () permett de
d débloquer
débl
un thread.
th d
synchronized(unObjet){
…
unObjet.notify(); // débloque un thread bloqué par unObjet
…
}
z
La méthode notifyAll() permet de débloquer tous les threads.
synchronized(unObjet){
…
unObjet.notifyAll(); // débloque tous les threads
// bloqués par unObjet
…
}
Langage Java – Threads et synchronisation
31
l moniteurs
les
it
M d l avec d
Module
des propriétés
iété particulières
ti liè
z
z
z
on n’a accès qu’aux primitives externes (publiques), pas aux
(privées)) ;
variables (p
les procédures sont exécutées en exclusion mutuelle et donc les
variables internes sont manipulées en exclusion mutuelle.
on peut bloquer et réveiller des tâches
tâches. Le blocage et le réveil
s’exprime au moyen de conditions.
Langage Java – Threads et synchronisation
32
R
Rappel
l : lles moniteurs
it
Conditions = variables, manipulables avec :
procédure attendre (modifié c : condition);
début
Bl
Bloque
lla tâ
tâche
h quii l’
l’exécute
é t ett l’
l’ajoute
j t d
dans la
l file
fil d’attente
d’ tt t associée
ié à c
Fin attendre;
fonction vide (c : condition) Æ un booléen;
début
si la file d’attente associée à c est vide alors
renvoyer(VRAI)
sinon
renvoyer(FAUX)
finsi
Fin vide;
procédure signaler (modifié c : condition);
début
si non vide(c) alors
extraire la première tâche de la file associée à c
la réveiller
finsi
Fin signaler;
Langage Java – Threads et synchronisation
33
M it
Moniteurs
en JJava (1)
z
z
En java on dispose de moniteurs simplifiés
Définition d’une classe
public
bli class
l
M
Moniteur
it
{
private type uneVariable;
public synchronized unePrimitive(
unePrimitive(. . .)
)
throws InterruptedException {
. . .
if (
(. . .)
)
wait(); // le thread se met en attente sur la cible
. . .
}
public synchronized unePrimitive(. . .) {
. . .
y
// réveil de la cible
notify();
. . .
}
Langage Java – Threads et synchronisation
34
M it
Moniteurs
en JJava (2)
z
I lé
Implémentation
t ti réduite
éd it des
d conditions
diti
public class Moniteur {
private type uneVariable;
private Object uneCondition = new Object();
public unePrimitive(. . .) // pas synchronized
throws InterruptedException {
. . .
if (. . .)
synchronized (uneCondition)
{uneCondition.wait();}
. . .
}
public synchronized unePrimitive(. . .) {
. . .
synchronized (uneCondition)
{uneCondition.notify();}
. . .
Langage Java }
– Threads et synchronisation
35
R d
Rendez-vous
avec un moniteur
it
Moniteur RDV;
Point d’entrée
Arriver
Lexique
n : un entier constant = ??
i : un entier;
_ : une condition;
tous_là
Début {Initialisations}
i Å 0;;
procédure Arriver();
début
i Å i + 1;
si i < n alors
attendre(tous_là);
fi i
finsi
signaler(tous_là); {Réveil en cascade}
fin Arriver;
Fin RDV;
Langage Java – Threads et synchronisation
36
Rendez-vous en Java : moniteur simplifié
class RendezVous {
private int nbattendus;
private int i;
// nombre attendus
// nombre arrivés
// constructeur
public RendezVous(int n) {
nbattendus = n;
i = 0;
}
public synchronized void arriver() throws
InterruptedException {
i++;
if (i < nbattendus)
b tt d ) {
wait();
};
notify();
}
}
Langage Java – Threads et synchronisation
37
Rendez-vous en Java avec condition
class RendezVous {
private int nbattendus;
private int i;
private
i
Object
j
tousla = new Object();
j
// nombre attendus
// nombre arrivés
// condition
i i
// constructeur
public RendezVous(int
p
(
n)
) {
nbattendus = n;
i = 0;
}
public void arriver() throws InterruptedException {
i++;
if (i < nbattendus) {
synchronized(tousla) {tousla.wait();}
};
synchronized(tousla) {tousla
{tousla.notify();}
notify();}
}
}
Langage Java – Threads et synchronisation
38
L Sé
Les
Sémaphores
h
en JJava
z
z
Il est inutile de définir des sémaphores en
Java, car les mécanismes fournis par le
l
langage
pour lla synchronisation
h i ti ett lle
partage de ressources sont suffisamment
puissants pour résoudre tous les problèmes
qu'on p
q
peut avoir à résoudre avec des
sémaphores.
Il est cependant intéressant de montrer
avec quelle facilité ces mécanismes
peuvent être
ê utilisés
ili é pour défi
définir
i d
des
sémaphores.
Langage Java – Threads et synchronisation
39
R
Rappel
l : Sé
Sémaphores
h
z
z
Mécanisme de synchronisation entre processus
processus.
Un sémaphore S est une variable entière, manipulable par
l’intermédiaire de deux opérations :
P (proberen) et V (verhogen)
acquire
release
acquire
acqu
e (S)
S Å (S − 1))
si S < 0, alors mettre le processus en attente ;
sinon on poursuit l’exécution
release (S)
S Å (S + 1) ; réveil d’un processus en attente.
Î
Î
acquire (S) correspond à une tentative de franchissement. S’il n’y a pas de
j t pour lla section
jeton
ti critique
iti
alors
l
attendre,
tt d sinon
i
prendre
d un jjeton
t ett entrer
t
dans la section (S), puis rendre son jeton à la sortie de la section critique.
Chaque dépôt de jeton release (S) autorise un passage. Il est possible de
déposer des jetons à ll’avance
avance
Langage Java – Threads et synchronisation
40
Réalisation
é
de la classe S
Semaphore
public class Semaphore {
private int xVal;
// la valeur du sémaphore
// En java, l'initialisation du sémaphore vient naturellement
// dans le constructeur
Semaphore (int valeur_initiale)
{ xVal = valeur_initiale; }
// Aquire : noter l'indispensable synchronized peut
// générer une InterruptedException (wait).
public synchronized void acquire() throws InterruptedException {
xVal = xVal - 1;
while(xVal < 0) wait();
}
// Release
public synchronized void release() {
xVal = xVal + 1;
if (xVal <= 0) notify();
}
}
Langage Java – Threads et synchronisation
41
G
Groupe
de
d th
threads
d
z
Un Thread peut faire partie d
d’un
un groupe de
Thread :
ThreadGroup tgl = new ThreadGroup(nom du groupe);
Thread t = new Thread(nom du goupe, nom du
thread);
Langage Java – Threads et synchronisation
42
A t
Autres
méthodes
éth d d
de lla classe
l
Th d
Thread
z
z
z
static int activeCount() nombre de threads actifs
du même groupe ou d’un
d un sous-groupe
sous groupe.
static void enumerate(Thread[ ] t) énumère dans
le tableau t les threads actifs du même groupe
ou d’un sous-groupe.
static
t ti Thread
Th d currentThread()
tTh d() retoune
t
une
référence au Thread courant.
Langage Java – Threads et synchronisation
43
Communication entre tâches (rappel)
( pp )
Partage de mémoire commune + exclusion mutuelle
Modèle général : producteur / consommateur
Producteur Æ Données Æ Consommateur
z
La communication est en général asynchrone : une des deux
tâches travaille en général plus vite que l’autre.
z
Pour limiter les effets de l’asynchronisme, on insère un tampon
entre le producteur et le consommateur :
Langage Java – Threads et synchronisation
44
Producteur/Consommateur
avec tampon (rappel)
Langage Java – Threads et synchronisation
45
Producteur/Consommateur avec tampon (rappel)
Moniteur Tampon; {Suppose Taille et Message connus}
Points d’entrée
déposer, retirer;
Lexique
nb : entier; {Nbre d’élt. dans le tampon (0..Taille)}
non_plein, non_vide : conditions; {Pour le blocage et le réveil}
tamp : tableau[0..Taille-1] de Messages;
tête, queue : entier; {O..Taille-1}
procédure déposer (consulté m:Message)
début
si nb = Taille alors
attendre(non_plein)
finsi
{Ajouter m au tampon}
nb ‡ nb + 1;
tamp[queue] ‡ m;
queue ‡ (queue+1) mod Taille;
signaler(non_vide);
fin déposer;
procédure retirer (consulté m:Message)
début
si nb = 0 alors
attendre(non_vide)
finsi
{ Enlever m du tampon
p }
m ‡ tamp[tête];
tête ‡ (tête+1) mod Taille;
nb ‡ nb - 1;
signaler(non_plein);
fin retirer;
Débutt
Déb
nb ‡ 0; tête ‡ 0; queue ‡ 0;
Fin Tampon;
Langage Java – Threads et synchronisation
46
Le problème des Philosophes et
d spaghettis
des
h tti
z
Le problème
L
blè
d
des philosophes
hil
h ett d
des spaghettis
h tti estt le
l
cas d'école concernant le problème classique de
partage de ressources
resso rces en informatiq
informatique
e ssystème.
stème Il
concerne l'ordonnancement des processus et
ll'allocation
allocation des ressources à ces derniers.
derniers La
situation est la suivante :
Î
Î
Î
cinq philosophes (initialement mais il peut y en avoir beaucoup
plus) se trouvent autour d'une table
chacun des philosophes a devant lui une assiette de spaghettis ;
à gauche de chaque plat de spaghetti se trouve une fourchette.
Langage Java – Threads et synchronisation
47
Le problème des Philosophes et
d spaghettis
des
h tti
z
Un philosophe n'a
n a que trois états possibles :
Î
Î
Î
z
penser pendant un temps indéterminé ;
être affamé (pendant un temps déterminé et fini sinon il y a
famine) ;
manger pendant un temps déterminé et fini.
Des contraintes
D
t i t extérieures
té i
s'imposent
'i
t à cette
tt
situation :
Î
Î
Î
quand
d un philosophe
hil
h a ffaim,
i il va se mettre
tt d
dans l'ét
l'étatt « affamé
ff é »
et attendre que les fourchettes soient libres ;
pour manger,
p
g , un p
philosophe
p a besoin de deux fourchettes : celle
qui se trouve à gauche de sa propre assiette, et celle qui se
trouve à gauche de celle de son voisin de droite (c'est-à-dire les
deux fourchettes qui entourent sa propre assiette) ;
si un philosophe n'arrive pas à s'emparer d'une fourchette, il
reste affamé pendant un temps déterminé, en attendant de
renouveler
l sa tentative.
i
Langage Java – Threads et synchronisation
48
Le problème des Philosophes et
d spaghettis
des
h tti
z
z
Le problème
L
blè
consiste
i t à ttrouver un comportement
t
t
des philosophes tel qu'ils puissent tous manger,
chac n à leur
chacun
le r to
tour.
r
Remarque : Les philosophes, s'ils agissent tous de
f
façons
naïves
ï
ett identiques,
id ti
risquent
i
t fort
f t de
d se
retrouver en situation d'interblocage. En effet, il
suffit
ffit que chacun
h
saisisse
i i
sa fourchette
f
h tt de
d gauche
h
et, qu'ensuite, chacun attende que sa fourchette de
droite se libère pour qu'aucun d'entre eux ne
puisse manger, et ce pour l'éternité.
Langage Java – Threads et synchronisation
49
E
Exemples
l en JJava
z
z
z
Yield
Yi
ld
Rendez-vous
Philosophes
Langage Java – Threads et synchronisation
50
Langage Java – Threads et synchronisation
51