Académique Documents
Professionnel Documents
Culture Documents
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
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
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
R. Grin
Java : threads
page 22
Si elle est termine, aucune exception nest ll i i lance mais rien nest excut
R. Grin
Java : threads
page 24
R. Grin
Java : threads
page 26
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
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
Voir lAPI java.nio pour les interruptions des attentes des entres-sorties
R. Grin Java : threads page 37
R. Grin
Java : threads
page 38
R. Grin
Java : threads
page 39
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
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
R. Grin
Java : threads
page 48
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); } } };
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
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
R. Grin
Java : threads
page 59
R. Grin
Java : threads
page 60
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
R. Grin
Java : threads
page 64
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
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
R. Grin
Java : threads
page 74
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
T inspecte intervalles rguliers la valeur de arretThread et s arrte quand sarrte arretThread a la valeur true
Java : threads page 81
R. Grin
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
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
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
R. Grin
Java : threads
page 92
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
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
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
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
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
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
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
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
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
R. Grin
Java : threads
page 125
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
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
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
R. Grin
Java : threads
page 147
R. Grin
Java : threads
page 148
R. Grin
Java : threads
page 150
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
R. Grin
Java : threads
page 155
R. Grin
Java : threads
page 157
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