Vous êtes sur la page 1sur 166

Threads

Universit de Nice - Sophia Antipolis


Version 3.3.4 3/4/11 Richard Grin Ri h d G i

Plan de cette partie


Prsentation des th d P t ti d threads Classe Thread Synchronisation entre threads wait et notify Difficults du multitche Divers complments Di l t Nouvelle API pour la concurrence

R. Grin

Java : threads

page 2

Ce C support expose l concepts d b t les t de base sur les threads en Java Quelques points de la nouvelle API pour la concurrence sont tudis la fin du support

R. Grin

Java : threads

page 3

Dfinitions
Un programme est multitche quand il lance (ou peut lancer) lexcution de plusieurs parties de son code en mme temps A un moment donn, il comporte plusieurs points dexcution li aux diff t parties i t d ti lis diffrentes ti qui s'excutent en parallle

R. Grin

Java : threads

page 4

Systmes dexploitation y p
Tous les systmes dexploitation modernes sont multitches et ils permettent lexcution de programmes multitches Sur une machine monoprocesseur cette excution en parallle est simule p Si le systme est premptif, il peut tout moment prendre la main un programme pour la donner un autre Sinon, Sinon un programme garde la main jusqu ce jusqu quil la cde un autre
R. Grin Java : threads page 5

Threads et processus p
Le multitche sappuie sur les processus ou les pp p threads (fil dexcution en franais) Chaque processus a son propre espace mmoire (espace o sont ranges les valeurs des variables utilises par le processus) Un processus peut lancer plusieurs threads qui se partagent le mme espace mmoire et peuvent donc se partager des variables Un thread U th d prend moins d ressources systme d i de t quun processus
R. Grin Java : threads page 6

Exemples de thread
Linterface graphique avec lutilisateur lance un g p q thread pour charger une image pour continuer traiter les vnements gnrs p les actions de g par lutilisateur Le serveur rseau 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 effectue en parallle par m n threads

R. Grin

Java : threads

page 7

Utilit du multitche
Sur S une machine multiprocesseurs il permet hi lti t damliorer les performances en rpartissant les diffrentes tches diff t t h sur diff t processeurs diffrents Par exemple, le calcul du produit de 2 matrices peut tre rparti en n tches parallles (ou k tches si le nombre k de processeurs est infrieur n) La rpartition des tches sur les processeurs est le p plus souvent faite automatiquement p le systme q par y qui offre le multitche
R. Grin Java : threads page 8

Utilit du multitche (2)


Sur S une machine monoprocesseur, il peut aussi hi t i tre intressant dutiliser le multitche pour
n n

modliser plus simplement ( (simulation par exemple) ) profiter des temps de pose dune tche (attente dentres-sorties ou dune action de lutilisateur) d t ti d ti d l tili t ) pour excuter dautres tches ragir plus vite aux actions de lutilisateur en rejetant l utilisateur une tche longue et non-interactive dans un autre (p p , g g thread (par exemple, chargement dune image ou lecture de donnes qui proviennent dun rseau)

R. Grin

Java : threads

page 9

Problmes du multitche
Il est souvent plus difficile d i un t t l diffi il dcrire programme multitche Et surtout, il est difficile de dboguer un programme qui utilise le multitche

R. Grin

Java : threads

page 10

Java et le multitche
Java supporte lutilisation des threads A l inverse de la plupart des autres langages, le linverse programmeur n'a pas utiliser des librairies natives du systme pour crire des programmes multitches

R. Grin

Java : threads

page 11

Threads en Java
A tout thread Java sont associs n un objet qui dtermine le code qui est excut par le thread n un objet qui contrle le thread et le reprsente auprs des objets de l application lapplication ; on lappellera le contrleur l appellera de thread

R. Grin

Java : threads

page 12

Interface Runnable
La classe de lobjet qui dtermine le code excuter doit implmenter linterface Runnable public interface Runnable { void run(); } mthode qui dtermine le code excuter par le thread
R. Grin Java : threads page 13

Un thread nest pas un objet ! n est


La mthode run() saute dun objet () j lautre en excutant les mthodes des classes de ces objets : o1.m1(); o2.m2(); ... Un thread est une unit dexcution qui, un moment donn, excute une mthode td t th d A un autre moment, ce mme thread pourra excuter une autre mthode d t t th d dune autre t classe
R. Grin Java : threads page 14

Contrleur de thread
Le contrleur dun thread est une instance de la d un classe Thread (ou dune classe fille) qui est lintercesseur entre le th d et l objets t li t t l thread t les bj t de lapplication n permet de contrler lexcution du thread (pour le lancer en particulier) n a des informations sur ltat du thread (son nom, sa priorit, sil est en vie ou non,) p )
n

R. Grin

Java : threads

page 15

Classe Thread Cl

R. Grin

Java : threads

page 16

Classe Thread
Elle implmente linterface R Runnable (mais la bl mthode run() ne fait rien) Une instance dune classe f de Thread peut fille donc tre la fois un contrleur de thread et dfinir le code excuter Lorsquune instance de Thread est cre, il faut q indiquer le code du thread qui sera contrl par cette instance

R. Grin

Java : threads

page 17

2 faons de crer un contrleur de thread


1re faon : utiliser le constructeur Thread(Runnable) de la classe Thread : 1. crer un Runnable (le code qui sera excut par le thread) 2. le passer au constructeur de Thread 2me faon : crer une instance dune classe fille de la classe Thread qui redfinit la mthode run()
R. Grin Java : threads page 18

Crer un contrleur de thread avec li t f linterface Runnable


class Tache implements Runnable { . . . public void run() { // Code qui sera excut par le thread . . . } } Tache tache = new Tache(); Thread t = new Thread(tache) ;
R. Grin Java : threads page 19

Crer un contrleur de thread avec une classe fille de la classe Thread


class ThreadTache extends Thread { . . . public void run() { // C d qui sera excut par l thread Code i le h d . . . } } ThreadTache threadTache = new ThreadTache();
R. Grin Java : threads page 20

Quelle faon utiliser ?


Si on veut h it d t hriter dune autre classe pour l t l la classe qui contient la mthode run(), on est oblig d choisir l 1re f bli de h i i la faon (Thread(Runnable)) Il est aussi plus simple dutiliser la 1re faon pour partager des donnes entre plusieurs threads Sinon, lcriture du code est (lgrement) ( g ) plus simple en utilisant la 2me faon
R. Grin Java : threads page 21

Nom dun thread d un


Des D constructeurs de Th d permettent de t t d Thread tt t d donner un nom au thread en le crant Le nom va faciliter le reprage des threads durant la mise au point

R. Grin

Java : threads

page 22

Lancer lexcution dun th d L l ti d thread


On appelle la mthode start() du contrleur de thread : t.start(); Le code du Runnable sexcute en parallle s excute au code qui a lanc le thread Attention, une erreur serait dappeler Att ti it d l directement la mthode run() : la mthode run() serait excute par l th d qui l () it t le thread i la appele et pas par un nouveau thread
R. Grin Java : threads page 23

Relancer lexcution dun thread


On ne peut relancer un thread qui a dj t lanc Si lexcution de la mthode run du thread nest pas encore t t termine, on obtient une i bti t
java.lang.IllegalThreadStateException

Si elle est termine, aucune exception nest ll i i lance mais rien nest excut

R. Grin

Java : threads

page 24

Vie du contrleur de thread


Le L contrleur d th d existe i d t l de thread i t indpendamment d t du thread, n avant le d t l dmarrage d th d du thread, par exemple, pour initialiser des variables d instances d'instances du contrleur n aprs la fin de lexcution de ce thread, par exemple pour rcuprer des valeurs exemple, calcules pendant lexcution du thread et ranges dans des variables dinstances du d instances contrleur
R. Grin Java : threads page 25

Utilisation d une classe interne dune


La mthode run est public Si on ne souhaite pas quelle soit appele qu elle directement, on peut utiliser une classe interne une classe fille de Thread pour implmenter Runnable

R. Grin

Java : threads

page 26

Utilisation dune classe interne anonyme


Si le code dune t h comporte peu d l d d tche t de lignes (sinon a devient vite illisible), on peut lancer son excution en parallle en utilisant l ti lll tili t une classe anonyme :
Thread t = new Th Th d Thread() { d() . . . Ou encore : public void run() { new Thread( new Runnable() { . . . . . . } public void run() { }; . . . t.start(); }
}); })
R. Grin Java : threads page 27

Mthodes publiques principales p q p p de la classe Thread


void start() static void sleep(long) throws InterruptedException void join() throws InterruptedException void interrupt() static boolean interrupted() int getPriority() void setPriority(int) static Thread currentThread() static void yield()
R. Grin Java : threads page 28

Thread courant
La mthode currentThread montre bien quun thread nest pas un objet Place dans une mthode de nimporte n importe quelle classe, elle retourne lobjet Thread qui contrle le thread qui excute cette mthode au moment o currentThread est appel On peut ainsi faire un traitement spcial dans le cas o la mthode est excut par un certain thread (par exemple le thread de rpartition
des vnements dans un GUI)
R. Grin Java : threads page 29

Attente de la fin d un thread dun


Soit un thread t t.join(); attend la fin de lexcution du thread contrl l excution par t On O remarquera quaprs l fi d l ti la fin de lexcution du thread t on peut encore envoyer de messages lobjet contrleur de thread t On peut aussi interroger la tche excute par le thread pour rcuprer le rsultat dun calcul effectu par le thread
R. Grin Java : threads page 30

Passer la main
La h d L mthode static d l classe Thread i de la l public static void yield() permet de passer la main un autre thread de priorit gale ou suprieure Elle permet d'crire des programmes plus portables qui s'adaptent mieux aux systmes multitches non premptifs

R. Grin

Java : threads

page 31

Dormir
La mthode static de la classe Thread
public static void sleep(long millis) throws InterruptedException

fait dormir le thread qui lappelle Si elle est excute dans du code synchronis, le thread ne perd pas le moniteur (au contraire de wait())

R. Grin

Java : threads

page 32

Mthode interrupt()
t.interrupt() t i t t() demande au thread contrl par t dinterrompre son excution di t ti Cette mthode ninterrompt pas brutalement le thread mais positionne son tat interrupted (lindicateur dinterruption)

R. Grin

Java : threads

page 33

Mthode interrupted()
La mthode static interrupted() renvoie la valeur de ltat interrupted du thread courant Attention, aprs lexcution de cette mthode, ltat interrupted d th d est mis f l lt t i t t d du thread t i false

R. Grin

Java : threads

page 34

Interrompre un thread
Pour qu un thread interrompe vraiment son quun excution, il doit participer activement sa propre interruption 2 cas : n le thread est en attente par les mthodes attente, sleep, wait, join, ou en attente dun entre-sortie entre sortie n toutes les autres situations

R. Grin

Java : threads

page 35

Interrompre un thread en attente (1)


Si le thread est en attente avec la mthode sleep, ou par wait ou join, la mthode interrupt provoque la leve dune d une java.lang.InterruptedException Le thread interrompu gre cette interruption dans un bloc catch qui traite cette exception
Malheureusement, une exception nest pas lev si le thread est en attente dune entre sortie (sauf avec d une entre-sortie InterruptibleChannel de NIO) ; seul lindicateur d e up o est positionn dinterruption es pos o
R. Grin Java : threads page 36

Interrompre un thread en attente (2)


Souvent le thread va repositionner lui-mme ltat interrupted ( lt t i t t d (pour t repr plus t d tre l tard par un Thread.interrupted()) car la leve dune I t l d InterruptedException enlve t dE ti l ltat interrupted du thread :
try { t . . . catch(InterruptedException e) { Thread.currentThread().interrupt(); }

Voir lAPI java.nio pour les interruptions des attentes des entres-sorties
R. Grin Java : threads page 37

Interrompre un thread p qui nest pas en attente (1)


En ce cas le thread doit vrifier priodiquement sil a t interrompu par la s il mthode static Thread.interrupted() Par P exemple avec une b l boucle d t l du type while (! Thread.interrupted()) { . . . // f i faire son t travail il }

R. Grin

Java : threads

page 38

Interrompre un thread p qui nest pas en attente (2)


Attention, lappel de la mthode interrupted() annule linterruption : si l interruption cette mthode renvoie true pour signaler une interruption et que le thread dcide de lignorer, un nouvel appel cette mthode renverra false (sauf si le thread est nouveau interrompu)

R. Grin

Java : threads

page 39

Raction une interruption


Le thread interrompu peut ragir L th d i t t i diffremment une interruption Il peut interrompre son excution avec un return ou en lanant une exception Il peut effectuer un traitement particulier en raction linterruption mais ne p p pas sinterrompre Il peut ignorer linterruption l interruption

R. Grin

Java : threads

page 40

Exemple 1
for (int i = 0; i < 100; i++) { try { y Thread.sleep(1000); } catch (InterruptedException e) { // Sinterrompt aprs avoir fait // le mnage ... return; } // Effectue un t it Eff t traitement t traitement(); }
R. Grin Java : threads page 41

Exemple 2 p
for (int i = 0; i < 100; i++) { // Effectue un t it Eff t traitement l t lourd d traitement(); if (Thread.interrupted()) { (Thread interrupted()) // Sinterrompt aprs avoir fait // le mnage ... return; }

R. Grin

Java : threads

page 42

Threads et exceptions
Si une exception nest pas traite ( ti t t it (par un bl bloc try-catch), elle interrompt lexcution du thread th d courant mais pas d autres th d t i des t threads La mthode run ne peut dclarer lancer une exception contrle car elle redfinit une mthode sans clause throws Une exception non saisie peut tre saisie par le groupe du thread ( g p (tudi p plus loin) )

R. Grin

Java : threads

page 43

Synchronisation entre threads

R. Grin

Java : threads

page 44

Section critique
Lutilisation de threads peut entraner des besoins de synchronisation pour viter les problmes lis aux accs simultans aux variables En programmation, on appelle section critique une partie du code qui ne peut tre excute en mme temps par plusieurs threads sans risquer de provoquer des anomalies de fonctionnement

R. Grin

Java : threads

page 45

Exemple de problme p p
Si x = 2, le code x = x + 1; excut par 2 threads peut donner en fin threads, dexcution 3 ou 4 suivant lordre dexcution : T1 : lit l valeur d x (2) la l de T2 : lit la valeur de x (2) T1 : calcul de x + 1 (3) T2 : calcul de x + 1 (3) T1 : range la valeur calcule dans x (3) T2 : range la valeur calcule d l l l l dans x (3) x contient 3 au lieu de 4 !
Java : threads page 46

1. 2. 3. 4. 4 5. 6.

R. Grin

Ncessaire synchronisation
Il f t donc viter l ti simultane d faut d it lexcution i lt de sections de code critiques par plusieurs threads th d En Java le code synchronis sur un objet est utilis pour synchroniser les threads et les empcher dexcuter en mme temps des portions de code Plusieurs threads ne peuvent excuter en p mme temps du code synchronis sur un mme objet j
R. Grin Java : threads page 47

2 possibilits pour synchroniser p p y du code sur un objet o


Mthode synchronise m (avec un message envoy lobjet o : o m( )) : l objet o.m()) public synchronized int m() { . . } Bloc Bl synchronis sur l bj t o : h i lobjet synchronized(o) { // l code synchronis le d h i . . . }

R. Grin

Java : threads

page 48

Moniteur d un objet dun


La L protection du code synchronis contre l t ti d d h i t les accs multiples repose sur les moniteurs des objets bj t Chaque objet Java possde un moniteur un moment donn, un seul thread peut p possder le moniteur dun objet j Si dautres threads veulent acqurir le mme moniteur, ils sont mis en attente, en attendant que le premier thread rende le moniteur
R. Grin Java : threads page 49

Acquisition et restitution cqu s t o est tut o dun moniteur


Un thread t acquiert automatiquement le moniteur dun objet o en excutant du code j synchronis sur cet objet o t rend le moniteur en quittant le code synchronis (ou se met en attente en appelant o.wait() o wait() dans le code synchronis) Il peut quitter le code synchronis normalement, ou si une exception est lance et non saisie dans le code synchronis
R. Grin Java : threads page 50

Rsum
Tant que t excute du code synchronis sur un objet o, l autres threads ne peuvent excuter bj t les t th d t t du code synchronis sur ce mme objet o (le mme code, ou nimporte quel autre code d i t l t d synchronis sur o) ; ils sont mis en attente Lorsque t quitte le code synchronis ou se met en attente par o.wait(), un des threads en attente peut commencer excuter le code synchronis Les autres threads en attente auront la main tour de rle (si tout se p ( passe bien) )
R. Grin Java : threads page 51

Exemple
public class Compte { private d bl solde; i t double ld public void d bli id deposer(double somme) { (d bl ) solde = solde + somme; } public double getSolde() { return solde; } }
R. Grin Java : threads page 52

Exemple (suite) p ( )
On lance 3 threads du type suivant :
Thread t1 = new Th Th d Thread() { d() public void run() { for (int i = 0; i < 100; i++) { compte.deposer(1000); } } };

A la fin de lexcution, on nobtient pas ncessairement 300.000

R. Grin

Java : threads

page 53

Exemple (fin) p ( )
Pour viter ce problme il faut rendre deposer synchronise : h i public synchronized void deposer(double somme) En fait, pour scuriser la classe contre les accs ,p multiples, il faudra aussi rendre getSolde synchronized car, en Java, un double nest pas y p lu en une opration atomique. Il faut donc viter que getSolde ne soit excut en mme temps g que deposer
R. Grin Java : threads page 54

Favoriser la dtection des problmes


En fait, si on excute le code prcdent sans , p rendre deposer synchronized, on obtiendra bien souvent (mais pas toujours) le bon rsultat a dpend du fonctionnement du multitche du systme dexploitation sous-jacent, et de la JVM Pour reprer plus facilement les problmes de multitche, on peut ajouter des appels aux mthodes yield ou sleep qui forcent le i ld l thread rendre la main, et permettre ainsi un autre thread de pouvoir sexcuter s excuter
R. Grin Java : threads page 55

Provoquer le problme
public class Compte { p private double solde; public void deposer(double somme) { double soldeTemp = solde; Avec tous les SE et JVM, la Thread.yield(); main pourra i solde = soldeTemp + somme; tre rendue } pendant lexcution de public double getSolde() { cette mthode return solde; t ld } }
R. Grin Java : threads page 56

Synchronisation et performances
L excution Lexcution de code synchronis peut nuire aux performances Il peut provoquer des blocages entre th d ; t d bl t threads peu de perte de performance sil ny a pas de blocage bl Du code synchronis peut empcher des optimisations (inlining) au moment de la compilation

R. Grin

Java : threads

page 57

Limiter la porte du code synchronis


Il f t synchroniser l moins d code possible faut h i le i de d ibl pour faciliter les accs multiples (les performances seront meilleures sil y a moins f t ill il i de threads en attente dun moniteur) Attention, viter dappeler lintrieur dune portion synchronise des mthodes quun client peut redfinir (dans une classe fille) ; en effet, une redfinition non approprie peut provoquer des pertes de performance ou mme des inter-blocages
R. Grin Java : threads page 58

Mthodes de classe synchronises


Si on synchronise une mthode static, on t ti bloque le moniteur de la classe On bloque ainsi tous les appels des mthodes synchronises de la classe (mais pas les appels synchroniss sur une instance de la classe)

R. Grin

Java : threads

page 59

Mthode Mth d synchronise et hritage h i t h it


La redfinition dune mthode synchronise d une dans une classe fille peut ne pas tre synchronise De mme, la redfinition dune mthode non synchronise peut tre synchronise

R. Grin

Java : threads

page 60

Synchronisation et y visibilit de modifications


La synchronisation permet dassurer la visibilit par l autres th d d l i ibilit les t threads de la modification dune variable par un thread (voir h happens-before d b f dans l section la ti difficults du multi-tche dans la suite de ce cours

R. Grin

Java : threads

page 61

wait et notify

R. Grin

Java : threads

page 62

Excution conditionnelle
Lorsqu un Lorsquun programme est multi tche la multi-tche, situation suivante peut se rencontrer : n U th Un thread t1 ne peut continuer son d t ti excution que si une condition est remplie n Le fait que la condition soit remplie ou non dpend dun autre thread t2 Par exemple, t1 a besoin du rsultat dun calcul effectu par t2 p

R. Grin

Java : threads

page 63

Excution conditionnelle (2)


Une solution coteuse serait que t1 teste la condition intervalles rguliers Les mthodes wait() et notify() de la classe Object permettent de programmer plus efficacement ce genre de situation

R. Grin

Java : threads

page 64

Schma dutilisation de wait-notify d utilisation


Cette utilisation demande un travail coopratif entre les threads t1 et t2 : Ils se mettent d accord sur un objet commun daccord objet Arriv lendroit o il ne peut continuer que si l endroit la condition est remplie, t1 se met en attente : objet.wait(); j (); Quand t2 a effectu le travail pour que la condition soit remplie, il le notifie : p , objet.notify(); ce qui dbloque t1
Java : threads page 65

1. 1 2. 2

3.

R. Grin

Besoin de synchronisation
Le L mcanisme d tt t i dattente-notification li un tifi ti objet met en jeu ltat interne de lobjet ; pour viter des it d accs concurrent cet t t i t t t tat interne, une synchronisation est ncessaire Les L appels objet.wait() et l objet.notify() (et objet.notifyAll()) ne peuvent donc tre effectus que dans du code synchronis sur objet Autrement dit, wait et notify ne peuvent tre lancs que dans une section critique
R. Grin Java : threads page 66

Mthode wait()
public final void wait() throws InterruptedException objet.wait() j () n ncessite que le thread en cours possde le moniteur de objet j n bloque le thread qui lappelle, jusqu ce quun autre thread appelle la mthode pp objet.notify() ou objet.notifyAll() n libre le moniteur de lobjet ( j (lopration p blocage du thread libration du moniteur est atomique)
R. Grin Java : threads page 67

Utilisation de wait
Mauvaise utilisation :
if (!condition) objet.wait();

si on quitte lattente avec le wait(), cela signifie quun autre thread a notifi que la qu un condition tait remplie n mais, aprs la notification, et avant le redmarrage de ce thread, un autre thread a pu prendre la main et modifier la condition
n

Le bon code (dans du code synchronis sur le mme objet que le code qui modifie la condition) :
while (!condition) { objet.wait(); }
R. Grin Java : threads page 68

Mthode notifyAll()
public final void notifyAll() objet.notifyAll() j y ()
n

ncessite que le thread en cours possde le moniteur de objet dbloque tous les threads qui staient bloqus sur lobjet avec objet wait() l objet objet.wait()

R. Grin

Java : threads

page 69

Mthode notifyAll()
Un seul des threads dbloqus va rcuprer le moniteur ; on ne peut prvoir lequel Les autres devront attendre quil relche le qu il moniteur pour tre dbloqus tour de rle, mais ils ne sont plus bloqus par un wait En fait, souvent ils se bloqueront nouveau euxmmes (sils sont dans une boucle while avec hil wait)

R. Grin

Java : threads

page 70

Mthode notify()
objet.notify() objet notify() n idem notifyAll() mais ne dbloque quun seul thread On ne peut p p prvoir q quel sera le thread dbloqu q et, le plus souvent, il vaut donc mieux utiliser notifyAll()
n

R. Grin

Java : threads

page 71

Dblocage des threads


Le thread dbloqu (et lu) ne pourra reprendre son excution que lorsque le thread qui la notifi rendra le moniteur de lobjet en quittant sa portion de code synchronis Le redmarrage et lacquisition se fait dans une opration atomique

R. Grin

Java : threads

page 72

notify perdus
Si un notifyAll() (ou notify()) est excut alors quaucun thread nest en attente, il est perdu : il ne dbloquera pas les wait() excuts ensuite

R. Grin

Java : threads

page 73

Exemple avec wait-notify wait notify


Les instances dune classe D Depot contiennent t des jetons Ces jetons sont n dposs p p par un p producteur n consomms par des consommateurs Les producteurs et consommateurs sont des threads

R. Grin

Java : threads

page 74

Exemple avec wait-notify


public class Depot { private int nbJetons = 0; pub c synchronized void do eJeto () { public sy c o ed o d donneJeton() try { while (nbJetons == 0) { wait(); } nbJetons--; } catch (InterruptedException e) {} }
R. Grin Java : threads page 75

Exemple avec wait-notify wait notify


public synchronized void recois(int n) { nbJetons += n; notifyAll(); tif All() }

R. Grin

Java : threads

page 76

Variante de wait
Si on ne veut pas attendre ternellement une t tt d t ll t notification, on peut utiliser une des variantes suivantes de wait : it
public void wait(long timeout) public void wait(long timeout timeout, int nanos)

Dans ce cas, le thread doit grer lui-mme le cas fait de connatre la cause de son dblocage (notify ou temps coul)

R. Grin

Java : threads

page 77

Moniteurs rentrants
Un thread qui a acquis le moniteur dun objet peut excuter les autres mthodes synchronises de cet objet ; il nest pas bloqu en demandant nouveau le moniteur

R. Grin

Java : threads

page 78

Affectations atomiques
Il est inutile de synchroniser une partie de code qui ne fait quaffecter (ou lire) une valeur une variable de type primitif de longueur 32 bits ou moins (int, short, ) En effet, la spcification du langage Java effet spcifie quune telle affectation ne peut tre interrompue pour donner la main un autre thread Mais, tt M i cette spcification nassure rien pour l ifi ti i les affectations de double et de long !
R. Grin Java : threads page 79

Stopper un thread
Si on stoppe un thread il arrte de sexcuter pp Il ne peut reprendre son excution ; si on veut pouvoir suspendre et reprendre lexcution du l excution thread, voir suspend et resume stop() est deprecated car le thread stopp peut laisser des objets dans un tat inconsistant car il relche leur moniteur quand il arrte son excution On O peut simuler stop en utilisant une variable t i l t tili t i bl

R. Grin

Java : threads

page 80

Simuler stop() p()


Pour rendre possible larrt d'un thread T, on peut utiliser une variable arretThread visible depuis T et les threads qui peuvent stopper T : n T initialise arretThread false lorsquil dmarre n pour stopper T, un autre thread met arretThread true
n

T inspecte intervalles rguliers la valeur de arretThread et s arrte quand sarrte arretThread a la valeur true
Java : threads page 81

R. Grin

Simuler stop() p()


arretThread doit tre dclare volatile si elle nest pas accde dans du code synchronis (volatile est tudi plus loin dans ce cours)

R. Grin

Java : threads

page 82

Interrompre un thread
Le mcanisme dcrit prcdemment pour stopper un thread ne fonctionne pas si le thread t th d est en attente (wait , sleep, attente tt t ( l tt t dun entre-sortie avec le paquetage java.nio depuis l SDK 1 4) d i le 1.4) Dans ce cas, on utilise interrupt() qui interrompt les attentes et met ltat du thread interrupted (voir la section sur la classe Thread du dbut de ce cours)
R. Grin Java : threads page 83

Suspendre et relancer un thread


suspend() et resume() sont d deprecated car d ils favorisent les interblocages (un thread suspendu ne relche pas les moniteurs quil possde) On peut les remplacer en utilisant une variable suspendreThread comme pour la mthode stop() Comme il faut pouvoir reprendre lexcution on l excution doit en plus utiliser wait() et notify()
R. Grin Java : threads page 84

Simuler suspend et resume


Pendant P d t son excution l th d scrute l ti le thread t la valeur de suspendreThread Si la valeur est true, le thread se met en attente avec wait sur un objet o Quand un autre thread veut relancer lexcution du thread, il met la variable , suspendreThread false et il appelle notify sur lobjet o y j
Rappel : les appels de wait et notify doivent se faire dans des sections synchronises sur o
R. Grin Java : threads page 85

Cycle de vie d'un thread


new Thread() Bloqu notify() Nouveau thread start() Eligible pour l'excution En excution yield() exit()en fin d'excution sleep() wait() it()

Mort
R. Grin Java : threads

page 86

Threads dmons
2 types de threads n les threads utilisateur n les dmons La diffrence : n la JVM fonctionne tant quil reste des threads qu il utilisateurs en excution n l JVM sarrte sil ne reste plus que d la t il t l des dmons Les dmons sont l seulement pour rendre service aux threads utilisateur. Exemple : ramasse-miettes
R. Grin Java : threads page 87

Threads dmons
La mthode void setDaemon(boolean on) de la l l classe Thread permet dindiquer que l th d h d t di di le thread sera un dmon (thread utilisateur par dfaut) Elle doit tre appele avant le dmarrage du thread par lappel de start()

R. Grin

Java : threads

page 88

Difficults lies au multitche

R. Grin

Java : threads

page 89

Difficults du multitche
Si un thread t doit attendre 2 notify de 2 autres threads th d t1 et t2 ce serait une f t d coder t t2, it faute de d
wait(); wait();

R. Grin

Java : threads

page 90

Difficults du multitche
En effet, les 2 notify() peuvent arriver y() p presque en mme temps : er notify() qui n le thread t1 envoie un 1 dbloque le 1er wait() ; il relche ensuite le moniteur et permet ainsi lautre thread t2 l autre t2 me notify() avant que le n denvoyer le 2 2me wait() ne soit lanc
n

le thread t reste bloqu ternellement sur le 2me wait() ( i ne recevra jjamais d notify()) it() (qui i de if ())

R. Grin

Java : threads

page 91

Comment coder cette situation ?


On compte le nombre de notify() avec une variable qui est i i bl i t incrmente d t dans une partie ti critique (synchronise) qui contient le notify() (pour t certain que la variable reprsente ( tre t i l i bl t vraiment le nombre de notify()) :
nbNotify++; bN tif ++ notifyAll();

R. Grin

Java : threads

page 92

Comment coder cette situation (suite)


Et on se met en attente dans une boucle (dans t tt t d b l (d une portion synchronise) :
while (nbNotify < 2) { wait(); }

Si on reoit 1 notify() entre les 2 wait(), nbNotify sera gal 2 et on sortira de la boucle sans faire le 2me wait()

R. Grin

Java : threads

page 93

viter la synchronisation
Comme l synchronisation a un cot non C la h i ti t ngligeable, il faut essayer de lviter quand cest possible t ibl Par exemple, si un seul thread crit une valeur d type int qui est l par plusieurs l de i lue l i autres threads, on peut se passer de synchronisation car les oprations de lecturecriture de int sont atomiques Mais attention, il y a de nombreux piges !
R. Grin Java : threads page 94

Partage de variables g par les threads


Soit v une variable partage par plusieurs threads Si le thread T modifie la valeur de v, cette , modification peut ne pas tre connue immdiatement par les autres threads Par exemple, le compilateur a pu utiliser un registre pour conserver la valeur de v pour T La spcification de Java nimpose la connaissance de cette modification par les autres threads que lors de lacquisition ou le relchement du moniteur dun objet (synchronized)
R. Grin Java : threads page 95

Volatile
Pour it ce problme, on peut d l P viter bl t dclarer l la variable v volatile On est ainsi certain que tous les threads partageront une zone mmoire commune pour ranger l valeur d l variable v la l de la i bl De plus, si une variable de type long et double est dclare volatile, sa lecture g q et son criture est garantie atomique

R. Grin

Java : threads

page 96

Attention !
Dans les anciennes versions de Java une Java, variable volatile init ne peut servir indiquer l initialisation linitialisation de variables non volatiles Par exemple, dans le code suivant :
v1 = 8; v2 = 3; init = true; ;

mme si init est lue comme vraie par un autre thread, v1 et v2 nont peut-tre pas t , p p initialises car le compilateur pouvait intervertir les instructions sil le juge utile p j g pour loptimisation p
R. Grin Java : threads page 97

Happens-before
Les L nouvelles versions d J ll i de Java ( partir d l ti de la version 5) formalisent les cas o une modification effectue par un th d est difi ti ff t thread t ncessairement connue par un autre thread (ce i i ifi ( qui signifie que, d dans t tous l autres cas, les t cette modification nest peut-tre par visible par l t th d) avec l notion d lautre thread) la ti de happens-before (arrive-avant) dfinie dans le chapitre 17 de la spcification d du langage
R. Grin Java : threads page 98

Dfinition de happens-before
Une U modification effectue par un th d T1 difi ti ff t thread est assure dtre visible par un thread T2 si et seulement si cette modification h t l t i tt difi ti happensbefore la lecture par le thread T2 Cette notion de happens-before nest pas ncessairement lie au temps ; il faut des conditions bien prcises pour quelle ait lieu Le transparent suivant rsume les cas de p bas niveau ; lAPI java.util.concurrent ajoute dautres cas de plus haut niveau j
R. Grin Java : threads page 99

Cas de happens-before pp
Dans un seul thread, une action happens-before toute action qui arrive aprs dans le code La libration dun moniteur happens-before lacquisition f future de ce moniteur Lcriture dans un champ volatile happensbefore la lecture future de la valeur de ce champ t1.start() happens-before toutes les actions () pp effectues par le thread t1 Les actions dun thread t1 happen-before les d un happen before actions dun thread t2 qui suivent linstruction t1.join()
R. Grin Java : threads page 100

Transitivit de Happens-before
Si une action A h ti happens-before une action B et b f ti t si B happens-before une action C, alors A happens-before C h b f Ce qui signifie, par exemple, que toute action effectue par un thread t1 happens-before toute action effectue par un thread t2, qui suit lexcution de l i d t1.join() Ce qui signifie aussi q le transparent q g que p prcdent Attention ! sur lutilisation errone dune variable volatile nest plus dactualit
R. Grin Java : threads page 101

Priorits

R. Grin

Java : threads

page 102

Principe de base
Si plusieurs threads de mme priorit sont en l i th d d i it t excution, on ne peut pas prvoir quel thread va prendre l main d la i Sils sont en attente dexcution, un thread de plus grande priorit prendra toujours la main avant un autre thread de priorit plus basse
Cependant, il peut arriver exceptionnellement quun thread continue son excution alors que des threads de i it d priorit suprieure sont en attente d ti i t tt t dexcution

R. Grin

Java : threads

page 103

Niveaux de priorit
Un U nouveau th d a l mme priorit que l thread la i it le thread qui la cr En gnral, tous les threads ont la mme priorit (NORM_PRIORITY ) Il faut faire appel la mthode setPriority p par si on veut modifier cette priorit p dfaut Le paramtre de setPriority doit tre inclus entre MIN_PRIORITY et MAX_PRIORITY
R. Grin Java : threads page 104

Autres classes lies aux threads : ThreadGroup et ThreadLocal

R. Grin

Java : threads

page 105

ThreadGroup
ThreadGroup reprsente un ensemble de h d n

threads, qui peut lui-mme comprendre un threadGroup ; on a ainsi une arborescence th dG i i b de threadGroup On peut ainsi jouer en une seule instruction sur la priorit des threads du groupe ou sur le fait que les thread soient des dmons ou non Cette classe nest pas trs utile et il est p conseill de ne pas lutiliser ; on se limite ici lessentiel
R. Grin Java : threads page 106

Lancer un thread d un groupe d'un


Pour crer un thread dun groupe, on doit utiliser le constructeur de la classe Thread qui prend un groupe en paramtre ; par exemple :
ThreadGroup tg = new MonGroupe("monGroupe"); Thread t = new MonThread(tg "monThread"); MonThread(tg, monThread ); t.start();

R. Grin

Java : threads

page 107

ThreadGroup et exceptions
La classe ThreadGroup contient la mthode
uncaughtException(Thread t, Throwable e)

qui est excute quand un des threads du groupe est stopp par une exception non saisie On peut redfinir cette mthode p p pour faire un traitement spcial sur les autres threads Depuis le JDK 5 il est plus simple dutiliser la 5, d utiliser mthode static setDefaultUncaughtException ou dinstance setUncaughtException de la d instance classe Thread pour traiter dune faon particulire les exceptions non attrapes
R. Grin Java : threads page 108

ThreadGroup et exceptions
class MyThreadGroup extends ThreadGroup { public MyThreadGroup(String s) { super(s); } public void uncaughtException(Thread t, Throwable e) { // On met ici le traitement qui doit tre excut // si un des threads du groupe reoit une exception // non attrape System.err.println("uncaught exception: " + e); } }

R. Grin

Java : threads

page 109

ThreadLocal ead oca


Cette classe de java.lang permet dassocier d associer un tat (typiquement une variable static p private) c aque thread sans c e ate) chaque ead sa s crer dinstances diffrentes Puisque la valeur nest connue que dun seul n est d un thread on vite ainsi les problmes lis aux accs concurrents Cest aussi un moyen commode dutiliser une valeur tout au long du droulement dun thread sans utiliser une variable connue par toutes les lignes de code concernes
R. Grin Java : threads page 110

Classe ThreadLocal<T> Mthodes de base


public void set(T valeur) met une valeur de type T dans lobjet de type l objet ThreadLocal public T get() bli t() rcupre la valeur rang dans lobjet de type ThreadLocal h d l public void remove() enlve la valeur de lobjet
R. Grin Java : threads page 111

Classe ThreadLocal<T> Initialisation de la valeur


protected T initialValue() renvoie la valeur renvoye par get si aucun set na t appel avant (renvoie null dans la classe ThreadLocal) Pour donner une valeur initiale la variable locale, il suffit de redfinir cette mthode dans une sous-classe de ThreadLocal

R. Grin

Java : threads

page 112

Exemple p
public class C { private static fi l Th i t t ti final ThreadLocal dL l tlSession = new ThreadLocal<Session>(); . . . public static getSession() { Session s = tlSession.get(); if (s == null) { s = getFabrique().newSession(); tlSession.set(s); En appelant C.getSession(), } tout le code parcouru par un thread pourra travailler avec la } mme session i
R. Grin Java : threads page 113

InheritableThreadLocal
Classe fille de ThreadLocal La diffrence avec ThreadLocal est que la valeur de ces variables (si elle a une valeur) est passe aux threads crs par le thread courant La mthode protected T childValue(T valeurDuPre) peut tre redfinie dans une classe fille pour donner au thread fils une valeur calcule partir de la valeur du thread pre (par dfaut cette dfaut, mthode renvoie la valeur passe en paramtre)
R. Grin Java : threads page 114

Timers

R. Grin

Java : threads

page 115

Classes Timer et TimerTask


Ces 2 classes du paquetage java.util permettent de lancer lexcution de tches des intervalles donns TimerTask a une mthode run() qui dtermine la tche accomplir Timer dtermine quand seront excutes les tches lui t h quon l i associe i Dans les 2 classes des mthodes cancel() permettent dinterrompre une tche ou toutes les tches associes un timer
R. Grin Java : threads page 116

Configuration du timer
Un timer peut d l U ti t dclencher une seule h l excution, ou pour dclencher des excutions d i t ti des intervalles rguliers ll li Pour lexcution des intervalles rguliers, le timer peut tre configur pour quil se cale le mieux par rapport au dbut des excutions (mthode ( h d scheduleAtFixedRate), ou par ) rapport la dernire excution (mthode schedule) )
R. Grin Java : threads page 117

Exemple d utilisation de timer dutilisation


final long debut = g System.currentTimeMillis(); TimerTask afficheTemps = new TimerTask() { public void run() { System.out.println( S t t i tl ( System.currentTimeMillis()- debut); } Dmarrer }; Timer timer = new Timer(); tout de suite Timer.schedule(afficheTemps, 0, 2000);
R. Grin Java : threads

Intervalles de 2 s entre 2 affichages

page 118

Timers et swing
Pour utiliser un ti P tili timer qui modifie l' ffi h i difi l'affichage en Swing, il faut utiliser la classe javax.swing.Timer j i Ti Cette classe utilise le thread de distribution des vnements pour faire excuter les tches

R. Grin

Java : threads

page 119

Utiliser des classes non sres vis--vis des threads (pas thread-safe )

R. Grin

Java : threads

page 120

Utiliser des classes non sres


Si cest possible, synchroniser explicitement p y p les accs aux objets partags en construisant des classes qui enveloppent les classes non sres, avec d mthodes synchronises des th d h i
(illustr par les collections)

Sinon, Sinon synchroniser les accs au niveau des clients de ces classes ; cest plus difficile et moins pratique On peut aussi sarranger pour que les mthodes non sres ne soient appeles que par un seul thread (illustr par swing et le thread
de distribution des vnements) )
R. Grin Java : threads page 121

Exemple des collections


Les L nouvelles collections (J ll ll ti (Java 2) ne sont t pas sres vis--vis des threads a permet n damliorer les performances en p environnement mono-thread n davantage de souplesse en environnement multi-threads : par exemple, pour ajouter plusieurs objets, on peut nacqurir quune n acqurir qu une seule fois un moniteur
R. Grin Java : threads page 122

Collections synchronises
LAPI des collections permet dobtenir une d ll ti t d bt i collection synchronise partir dune collection non synchronise, par exemple ll ti h i l avec la mthode static Collections.synchronizedList C ll ti h i dLi t

R. Grin

Java : threads

page 123

Protection des collections non synchronises


Il faut synchroniser explicitement les modifications des collections : private ArrayList al; . . . Synchronized(al) { Avantage sur g al.add(); al.add( ); Vector : une al.add(); seule acquisition } de d moniteur pour it
plusieurs modifications
R. Grin Java : threads page 124

Protection des collections non synchronises


Cette technique nest pas toujours possible si les classes non synchronises font appel elles mmes elles-mmes des objets non-protgs auxquelles on ne peut accder

R. Grin

Java : threads

page 125

Collections thread-safe thread safe


Le paquetage java util concurrent du java.util.concurrent JDK 5 (voir section suivante) contient des collections thread safe qui offrent scurit et thread-safe performance en environnement multi-tche : ConcurrentHashMap, ConcurrentHashMap CopyOnWriteArrayList, CopyOnWriteArraySet Il ne faut les utiliser que lorsquil y a des risques dus des d d modifications par plusieurs th d difi ti l i threads (moins performantes que les collections normales ) l )
R. Grin Java : threads page 126

Paquetage java.util.concurrent

R. Grin

Java : threads

page 127

Nouvelle API
Le L JDK 1 5 a ajout un nouveau paquetage 1.5 j t t qui offre de nombreuses possibilits, avec de bonnes performances b f Le programmeur naura ainsi pas rinventer la roue pour des fonctionnalits standards telles que les excutions asynchrones, les gestions de collections accdes par plusieurs threads (telles que les files dattentes), les blocages en lectures/critures, etc.
R. Grin Java : threads page 128

Ce C cours ne f it que survoler quelques fait l l possibilits offertes par cette API Pour plus de prcisions se reporter la javadoc de lAPI et ses tutoriels

R. Grin

Java : threads

page 129

Problmes avec Runnable


La mthode run ne peut renvoyer une valeur et elle ne peut lancer dexceptions contrles par l compilateur le il t Les valeurs calcules par la mthode run doivent donc tre rcupres par une mthode de type getValeur() et les exceptions contrles doivent tre attrapes et signales dune faon dtourne au code qui a l i lanc run
R. Grin Java : threads page 130

Nouveau cadre
La L nouvelle API f ll fournit un nouveau cadre it d pour faciliter et enrichir les possibilits lors du lancement d t h en parallle l t de tches lll Linterface Callable amliore Runnable Future facilite la rcupration des valeurs p calcules en parallle Executor et Executors dcouplent la soumission de tches et leur excution, et offrent une gestion de pools de threads
R. Grin Java : threads page 131

Considrations techniques
De nouvelles instructions ont t ajoutes aux j processeurs pour faciliter leur utilisation en environnement multi-curs Par exemple, dans les processeurs Intel, l instruction compare and swap (CAS), linstruction compare-and-swap (CAS) en une seule opration atomique, (la main ne peut tre donne un autre thread pendant son excution) compare la valeur dun emplacement mmoire une valeur donne et, selon le rsultat de la comparaison, modifie un emplacement mmoire
R. Grin Java : threads page 132

Considrations techniques
La JVM a t adapte p p pour bnficier des ces nouvelles instructions La nouvelle API de java.util.concurrent sappuie sur ces nouveauts pour amliorer la gestion du multitche en particulier pour multitche, amliorer les performances, par rapport l utilisation lutilisation de synchronize

R. Grin

Java : threads

page 133

Interface Callable<V>
Elle Ell reprsente une t h excuter ( t tche t (par ExecutorService), qui renvoie une valeur de type V Une seule mthode qui excute la tche : V call() throws Exception La classe Executors contient des mthodes pour envelopper les anciennes interfaces Runnable, PrivilegedAction et PrivilegedExceptionAction, et les transformer en Callable
R. Grin Java : threads page 134

Interface Executor
Reprsente un objet qui excute d t h R t bj t i t des tches quon lui a soumises La soumission dune tche est effectue par la seule mthode de linterface : void execute(Runnable tche)

R. Grin

Java : threads

page 135

Excution des tches


Les tches L t h soumises un excuteur ne sont i t t pas ncessairement excutes par des threads th d mais cest l plus souvent l cas i t le l t le Au contraire de la classe Thread qui lance immdiatement un thread avec la mthode start(), un excuteur peut choisir le moment et la manire dexcuter les tches quon lui a soumises

R. Grin

Java : threads

page 136

Interface Future<V>
Reprsente l rsultat d R t le lt t dune t h excute tche t en parallle Les mthodes de linterface permettent de retrouver le rsultat du travail (get), dannuler l tche ( d l la h (cancel) ou d savoir si l ) de i i la tche a termin son travail (isDone) ou a t annule ( l (isCancelled) )

R. Grin

Java : threads

page 137

Mthodes get
V get() t() rcupre le rsultat du travail ; bloque si le travail nest pas encore t t il t termine i V get(long dlai, TimeUnit unit) idem get() mais ne bl id i bloque quau plus l l le temps du dlai pass en paramtre Exemple : get(50L, TimeUnit.SECONDS)

R. Grin

Java : threads

page 138

Interface ExecutorService
ExecutorService est une sous interface E t S i sous-interface de Executor Elle ajoute des mthodes pour grer la fin de lexcution des tches et rcuprer un Future comme rsultat d l soumission l de la i i dune tche

R. Grin

Java : threads

page 139

Mthodes de ExecutorService
Mthodes submit pour soumettre une tche b it (Callable ou Runnable) et rcuprer un Future qui reprsente lexcution de la tche F t l excution <T> Future<T> submit(Callable<T> task) Les mthodes avec Runnable en paramtre renvoient un Future dont la mthode get renvoie la valeur null ou une certaine valeur passe en paramtre aprs la fin de lexcution (car un Runnable ne renvoie pas de valeur)
R. Grin Java : threads page 140

Mthodes de ExecutorService
Mthodes invokeAll et invokeAny pour excuter une collection d t h ( ll bl ) et t ll ti de tches (Callable) t renvoyer le rsultat (Future) de toutes les tches (InvokeAll) ou dune seule qui sest t h ( k ll) d l i t excute correctement (invokeAny) ; un temps maximum d ti peut t pass en i dexcution t tre paramtre et les tches non termines dans le temps imparti sont arrtes t i ti t t Par exemple,
<T> List<Future<T>> invokeAll( Collection<? extends Callable<T>> tasks) throws InterruptedException
R. Grin Java : threads page 141

Mthodes de ExecutorService
Mthodes shutdown et shutdownNow pour p arrter lactivit de lexcuteur, dune faon civilise (avec shutdown les tches en ( cours se terminent normalement ; seules les tches en attente dexcution ne seront pas p excutes) ou brutales (avec shutdownNow les tches en cours dexcution sont stoppes) List<Runnable> shutdownNow() renvoie la liste des tches qui taient en attente d excution dexcution
R. Grin Java : threads page 142

Mthodes de ExecutorService
La mthode i Sh td isShutdown indique si lexcuteur a t arrt La mthode isTerminated indique si toutes les tches en cours dexcution au moment de larrt ont termin leur excution La mthode awaitTermination bloque en attendant la fin de lexcution des tches aprs un shutdown (un dlai maximum dattente est pass en paramtre)
R. Grin Java : threads page 143

Interface ScheduledExecutorService
Hrite de ExecutorService 4 mthodes schedule qui crent un excuteur et lancent les excutions Permet de donner un dlai avant lexcution l excution ou de faire excuter priodiquement une tche (comme les timers) On peut indiquer une priodicit moyenne pour l excutions ou un i t les ti intervalle fi entre ll fixe t la fin dune excution et le dbut de la prochaine excution h i ti
R. Grin Java : threads page 144

Classe Executors
Contient des mthodes static utilitaires t ti pour dautres interfaces du paquetage : Executor, E E t ExecutorService, t S i Callable,

R. Grin

Java : threads

page 145

Mthodes static callable


Les mthodes callable renvoient un Callable qui enveloppe un Runnable, PrivilegedAction ou g PrivilegedExceptionAction privilegedCallable(Callable) est rserve un appel dans la mthode doPrivileged de la classe AccessController ; elle renvoie un Callable dont les autorisations ne dpendent pas du contexte dappel (voir cours sur la scurit en Java)
R. Grin Java : threads page 146

Les fabriques (1)


Noms des mthodes commencent par new N d th d t Une fabrique de Thread (java.util.ThreadFactory) peut tre ( ) passe en paramtre si on veut des types spciaux de threads (par exemple avec une certaine priorit, ou dune certaine sous-classe de d Thread) )

R. Grin

Java : threads

page 147

Les fabriques (2)


newCachedThreadPool : cre un pool de C h dTh dP l threads rutilisables n Les threads non utiliss depuis 1 minute sont supprims n Nouveaux threads crs si ncessaire newFixedThreadPool : cre un pool e ed ead oo p contenant un nombre fixe de threads n Nombre de threads passs en paramtre

R. Grin

Java : threads

page 148

Les fabriques (3)


newSingleThreadExecutor : cre un excuteur qui excutera les tches les unes aprs les autres newScheduledThreadPool : cre un pool de threads qui peuvent excuter des commandes aprs un certain dlai ou priodiquement newSingleThreadScheduledExecutor : cre un excuteur qui peut excuter d t i t t des commandes aprs un certain dlai ou priodiquement, ne priodiq ement une commande la fois
R. Grin Java : threads page 149

Exemple d utilisation des pools dutilisation


ExecutorService pool = Executors.newFixedThreadPool(10); Runnable r = new R R bl Runnable() { bl () public void run() { ... } }; pool.execute(r);

R. Grin

Java : threads

page 150

Exemple de pool avec Callable


ExecutorService pool = p Executors.newFixedThreadPool(10); g Callable<Integer> c = new Callable<Integer>() { pub c public Integer call() { tege ca () ... } }; Future<Integer> f = pool submit(c); pool.submit(c); ... int v = f.get(); f get();
R. Grin Java : threads page 151

Les L quelques t l transparents suivants tudient t i t t di t les nouvelles collections thread-safe

R. Grin

Java : threads

page 152

Classe ConcurrentHashMap
Au contraire de H hT bl les lectures ne HashTable, bloquent ni les autres lectures ni mme les mises j i jour Une lecture reflte ltat de la map aprs la dernire mise jour compltement termine (celles en cours ne sont pas prises en compte) Les mthodes sont peu p p prs les mmes que celles de HashMap
R. Grin Java : threads page 153

Classe CopyOnWriteArrayList
Variante thread safe de A thread-safe ArrayList dans Li t laquelle toutes les oprations de mise jour sont effectues en faisant une copie du t bl t ff t f i t i d tableau sous-jacent (le tableau nest jamais modifi) Cette variante nest intressante que lorsque les parcours de la liste sont bien plus frquents que les mises jour Les itrateurs refltent la liste au moment o ils ont t crs ; ils ne peuvent modifier la liste Idem pour CopyOnWriteArraySet p py y
R. Grin Java : threads page 154

Interfaces pour files dattente d attente


Linterface j java.util.Queue, introduite par til Q le JDK 1.5, est semblable List mais correspond une fil d tt t : elle ne d file dattente ll permet des ajouts qu la fin et des suppressions quau db t i dbut Cette contrainte permet plus doptimisation que pour l i l les implmentations d List i de

R. Grin

Java : threads

page 155

Interfaces pour files dattente d attente


Linterface Li t f java.util.concurrent.BlockingQueue hrite de Q Queue et ajoute une mthode qui se bloque lorsquelle veut supprimer un lment dans une file vide (t k ) et une mthode qui (take) se bloque lorsquelle ajoute un lment dans une file pleine ( t) (put) Elle permet dimplmenter des files pour des producteurs et des consommateurs
R. Grin Java : threads page 156

Classes pour files dattente d attente


BlockingQueue est implment par les Bl ki Q classes n LinkedBlockingQueue n PriorityBlockingQueue n ArrayBlockingQueue n SynchronousQueue

R. Grin

Java : threads

page 157

Synchronisation des threads


La L nouvelle API d concurrence offre d ll de ff des objets pour faciliter le codage des programmes qui utilisent plusieurs t it i tili t l i traitement t en parallle La l L classe Semaphore i l implmente un smaphore classique Les classes CountDownLatch et CyclicBarrier reprsentent des structures un peu plus complexes qui facilitent la synchronisation de plusieurs threads y
R. Grin Java : threads page 158

Semaphore
Un U smaphore gre d ressources li it h des limites La mthode public void acquire() demande une ressource et bloque jusqu ce quil y en ait une disponible ; lorsque la mthode retourne, une ressource en moins est disponible via le smaphore La mthode public void release() q rend une ressource ; lorsque la mthode retourne, une ressource de plus est disponible via le smaphore
R. Grin Java : threads page 159

Semaphore
Plusieurs variantes des mthodes d b Pl i i t d th d de base acquire et release sont disponibles (pour acqurir ou rendre plusieurs ressources en i d l i mme temps ou pour ne pas se bloquer en attente de ressources) tt t d )

R. Grin

Java : threads

page 160

CountDownLatch et CyclicBarrier
Les classes CountDownLatch et CyclicBarrier facilitent la dcomposition dun traitement en plusieurs sous-traitements parallles A certains points dexcution le traitement ne peut se poursuivre que si l sous-traitements i i les i ont termin une partie de leur travail

R. Grin

Java : threads

page 161

CyclicBarrier
Reprsente une b i d i l R t barrire derrire laquelle n ll threads (n est un paramtre du constructeur) qui reprsentent l sous-traitements, i t t les t it t attendent par la mthode barriere.await() Quand les n threads y sont arrivs, la barrire se lve et les threads continuent leur excution La barrire est cyclic car elle se rabaisse y ensuite, et les threads y sont nouveau bloqus
R. Grin Java : threads page 162

CyclicBarrier
Un U constructeur permet de passer en t t td paramtre un Runnable qui sera excut juste avant que la b i ne se relve t l barrire l

R. Grin

Java : threads

page 163

CountDownLatch
Rle similaire une barrire mais il ne peut servir quune seule fois et le fonctionnement est diffrent : l arrive au point dattente est larrive d attente dissocie de lattente elle-mme Le constructeur prend en paramtre un nombre n Les sous-traitements peuvent dcrmenter ce nombre par cdl.countDown() Des threads peuvent aussi attendre que n soit gal 0 par cdl.await()
R. Grin Java : threads page 164

CountDownLatch
Peut t P t tre utilis pour l mme usage quune tili le barrire : les sous-traitements appellent countDown et await juste aprs tD it Mais aussi comme un starter : n est initialis 1 et tous les threads commencent par attendre par await ; ensuite un thread starter appelle countDown pour f i ll faire dmarrer tous les threads

R. Grin

Java : threads

page 165

D autres Dautres cas de happens-before happens before


Lajout dun objet dans une collection threadj j safe de cette API happens-before un accs ou une suppression de lobjet dans la collection pp j Les actions effectues pour le calcul dun Future happens-before la rcupration de la happens before valeur du Future Une action excute par un thread avant une attente une barrire cyclique (await) happensbefore laction (optionnelle) excute par la l action barrire au moment o elle se lve, qui ellemme, mme happens-before une action qui suit await
R. Grin Java : threads page 166

Vous aimerez peut-être aussi