27
Les threads en Java Arnaud Labourel Courriel : [email protected] Universit´ e de Provence 26 janvier 2012 Arnaud Labourel, [email protected] Les threads en Java

Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : [email protected] Universit e de Provence 26

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Les threads en Java

Arnaud LabourelCourriel : [email protected]

Universite de Provence

26 janvier 2012

Arnaud Labourel, [email protected] Les threads en Java

Page 2: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Au Temps des Dinosaures...

et des cartes perforees, les ordinateurs etaient de grossesinstallations sur lesquelles on pouvait soumettre untravail puis venir recuperer le resultat quelques heuresplus tard.

Si un probleme se produisait en cours d’execution, on nele savait que plus tard et le temps affecte etait perdu...

Arnaud Labourel, [email protected] Les threads en Java

Page 3: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Multi-Taches

Le multi-taches permet de

optimiser l’utilisation des ressources (CPU, ...)

faciliter la programmation (modularisation)faciliter l’equite

Serveur multi-utilisateursStation mono-utilisateur : systeme plus “reactif”

Arnaud Labourel, [email protected] Les threads en Java

Page 4: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Processus et Threads

Une activite est une suite d’instructions (executionsequentielle.)

Un systeme est multi-tache s’il peut faire coexisterplusieurs activites au sein d’un meme environnement.

Un processus est une activite seule au sein d’unenvironnement restreint (memoire ...).

Au contraire un thread (ou processus leger) partage toutun environnement memoire avec d’autres threads.

Arnaud Labourel, [email protected] Les threads en Java

Page 5: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Exemples

Activites :

processus UNIX

threads POSIX

threads Java

Systemes d’exploitation :

Windows (NT, 2000, XP, Vista, seven)

SolarisUnix :

Les Unix proprietaires (AIX, HP UX, ...)BSDLinux (vrais threads depuis 2.6)Mac OS X

Arnaud Labourel, [email protected] Les threads en Java

Page 6: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Creation de Threads en Java

Deux manieres de faire :Classe Thread

methode run : code de l’activitemethode start : lancement de l’activitemethodes de controle ...=⇒par heritage de Thread.

interface Runnableune unique methode (abstraite) public void run() :code de l’activitepar implementation de Runnable+ constructeurs de la classe Thread

Arnaud Labourel, [email protected] Les threads en Java

Page 7: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Creation de Threads en Java

Deux manieres de faire :Classe Thread

methode run : code de l’activitemethode start : lancement de l’activitemethodes de controle ...=⇒par heritage de Thread.

interface Runnableune unique methode (abstraite) public void run() :code de l’activitepar implementation de Runnable+ constructeurs de la classe Thread

Arnaud Labourel, [email protected] Les threads en Java

Page 8: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Rappels : “Heritages Multiples”

Pourquoi deux manieres de faire ?

Rappel : Java n’autorise pas l’heritage multiple.

Une classe ne peut etre l’extension (ne peux heriter) qued’une seule classe.Par contre elle peut implementer plusieurs interfaces.Rappel : une interface n’a pas de variable d’instance etn’a que des methodes abstraites...

Arnaud Labourel, [email protected] Les threads en Java

Page 9: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Comment choisir entre les deux solutions ?

Heriter de Thread : quand on n’a pas besoind’heriter d’une autre classe.

Implementer Runnable : quand on souhaiteheriter d’une autre classe.

Arnaud Labourel, [email protected] Les threads en Java

Page 10: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Exemple : ExThread.javac l a s s ExThread extends Thread {

i n t i d ;

ExThread ( i n t v a l ) {/∗ c o n s t r u c t e u r ∗/i d = v a l ;}

/∗ Methode e x e c u t e e par l e t h r e a d ∗/publ ic void run ( ) {. . .}. . .

fo r ( i n t i =1; i<=n ; i ++)new ExThread ( i ) . s t a r t ( ) ;

. . .}

Arnaud Labourel, [email protected] Les threads en Java

Page 11: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Exemple : ExRunnable.javac l a s s ExRunnable implements Runnable {

i n t i d ;

ExThread ( i n t v a l ) {/∗ c o n s t r u c t e u r ∗/i d = v a l ;}

/∗ Methode e x e c u t e e par l e t h r e a d ∗/publ ic void run ( ) {. . .}. . .

fo r ( i n t i =1; i<=n ; i ++)new Thread (new ExRunnable ( i ) ) . s t a r t ( ) ;

. . .}

Arnaud Labourel, [email protected] Les threads en Java

Page 12: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Remarque Importante

Ne pas confondre l’activite (le thread : processus leger)avec la structure de donnees (le Thread : l’objet).

Arnaud Labourel, [email protected] Les threads en Java

Page 13: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Information sur les Threads

static int activeCount() : renvoie le nombre dethreads actuellement executes

static int enumerate(Thread[] tarray) :stocke l’ensemble des Threads du meme groupedans le tableau et renvoie le nombre de threads.

static Thread currentThread() : renvoie leThread correspondant au thread en train d’etreexecute. (utile notamment avec Runnable)

Arnaud Labourel, [email protected] Les threads en Java

Page 14: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Autres methodes sur les Threads

void setName(String name) : change le nom duThread

String getName() : retourne le nom du Thread

new Thread(ThreadGroup group,Runnable target , String name) : cree un

Thread dans un groupe.

new ThreadGroup(”Mon groupe”) : cree ungroupe de Thread

Arnaud Labourel, [email protected] Les threads en Java

Page 15: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Ordonnancement

L’ordonnanceur de la JVM n’est pas tenu d’etreequitable. Les threads de basses priorites ne sontexecutes que si les threads de hautes priorites sontbloques...

void setPriority ( int ) : fixer la priorite du thread

int getPriority () : renvoie la priorite du thread

static void yield () : provoque une “pause” duthread en cours et un reordonnancement (indicatifseulement...)

L’ordonnanceur n’est pas tenu de tenir compte despriorites...=⇒inutilisable de maniere portable.

Arnaud Labourel, [email protected] Les threads en Java

Page 16: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Manipulation des Threads

mise en attente :void sleep (long millis )void sleep (long millis , int nanos)

NB : pas de garantie temps-reelattente de l’arret d’un thread donne :

void join ()void join (long millis ) avec delaivoid join (long millis , int nanos) avec delai

interruption d’un thread :

void interrupt () : un thread “interrompt” (envoie uneInterruptedException ) un autre.

Arnaud Labourel, [email protected] Les threads en Java

Page 17: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Rappels : Exceptions

Certaines des methodes precedentes (bloquantes)demandent une gestion explicite des interruptions partry{ ... } catch(InterruptedException e){ ... }Une exception correspond en general a un deroulementanormal du programme. De plus, dans le casmulti-threade, cela peut correspondre a certainesinteractions entre threads.

Erreur inhabituelle =⇒gestion d’erreur classique

Declenchement d’une exception

Gestion des interruptions/exceptions.

Arnaud Labourel, [email protected] Les threads en Java

Page 18: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Throwable

unchecked exception : erreur engendree par la JVM(interaction systeme) =⇒ne doit pasnecessairement etre geree.

checked exception : erreur definie par l’utilisateur,doit necessairement etre geree (=⇒throws)

Ici, plus particulierement, InterruptedException .

Arnaud Labourel, [email protected] Les threads en Java

Page 19: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

try, catch, finally

. . .t ry {/∗ a p p e l a une methode l a n c a n t des e x c e p t i o n s ∗/

. . .} catch ( TypeExcept ion e ){

. . .} catch ( A u t r e T y p e E x c e p t i o n e ){

. . .} f i n a l l y { // t o u j o u r s e x e c u t e

. . .}

Arnaud Labourel, [email protected] Les threads en Java

Page 20: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Variables Partagees

Les variables de la classe declarees en static sontpartagees entre tous les threads associes a cette classe.

Il est conseille de rajouter le mot clef volatile pourproteger la variable de certaines “optimisations” de laJVM.

Voir, plus tard, le package atomic, puis les questions devisibilite et du modele memoire Java.

Arnaud Labourel, [email protected] Les threads en Java

Page 21: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Synchronisation et Exclusion Mutuelle

Le mot-clef synchronized permet de gerer lasynchronisation des acces a la memoire partagee.

Un appel a une methode declaree synchronized d’uneinstance donnee est en exclusion mutuelle vis-a-vis detous les appels de methodes declarees synchronized surcette meme instance.

Arnaud Labourel, [email protected] Les threads en Java

Page 22: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Tres Important : Methodologie

Il faudra toujours bien separer donnees partagees etactivites=⇒au moins Deux classes.

Voir VariablePartagee.java,VariableSynchronized.java,VariableBienSynchronized.java.

Arnaud Labourel, [email protected] Les threads en Java

Page 23: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

VariablePartagee.java

c l a s s E n t i e r P a r t a g e{

i n t v a l e u r ;

E n t i e r P a r t a g e ( i n t v a l e u r ){t h i s . v a l e u r = v a l e u r ;

}

v o i d decremente ( i n t dec ){v a l e u r −= dec ;

}

p u b l i c S t r i n g t o S t r i n g (){r e t u r n S t r i n g . v a l u e O f ( v a l e u r ) ;

}}

c l a s s V a r i a b l e P a r t a g e e extends Thread {s t a t i c v o l a t i l e E n t i e r P a r t a g e v a r p a r t ;i n t i d ;

V a r i a b l e P a r t a g e e ( i n t i d ) {t h i s . i d = i d ;

}

p u b l i c v o i d run ( ) {w h i l e ( v a r p a r t . v a l e u r >= i d ){

a f f i c h e ( ” Avant ”+v a r p a r t ) ;v a r p a r t . decremente ( i d ) ;a f f i c h e ( ” Apr e s ”+v a r p a r t ) ;t r y { s l e e p ( 0 , 0 ) ;}catch ( I n t e r r u p t e d E x c e p t i o n e ){ a f f i c h e ( ” I n t e r r o m p u ” ) ;}

}a f f i c h e ( ” Termine ( ”+v a r p a r t+” ) ” ) ;

}

v o i d a f f i c h e ( S t r i n g s ){System . out . p r i n t l n ( Thread . c u r r e n t T h r e a d ( ) . getName ()+” : ”+s ) ;

}

p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {i n t n = 3 , v a l =9;

v a r p a r t = new E n t i e r P a r t a g e ( v a l ) ;f o r ( i n t i =1; i<=n ; i ++)

new V a r i a b l e P a r t a g e e ( i ) . s t a r t ( ) ;System . out . p r i n t l n ( ”Main : v a l e u r = ”+v a l ) ;System . out . p r i n t l n ( ”Main : I l y a ”+n+” t h r e a d s , l a r e g l e du j e u e s t chaque t h r e a d ne ” ) ;System . out . p r i n t l n ( ”Main : peut r e t i r e r qu ’ un nombre de p o i n t s e g a l e a son i d e n t i t e .\n” ) ;

}}

Arnaud Labourel, [email protected] Les threads en Java

Page 24: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

VariablePartageeSynchronized.java

c l a s s E n t i e r P a r t a g e{

i n t v a l e u r ;

E n t i e r P a r t a g e ( i n t v a l e u r ){t h i s . v a l e u r = v a l e u r ;

}

s y n c h r o n i z e d v o i d decremente ( i n t dec ){v a l e u r −= dec ;

}

p u b l i c S t r i n g t o S t r i n g (){r e t u r n S t r i n g . v a l u e O f ( v a l e u r ) ;

}}

c l a s s V a r i a b l e P a r t a g e e Sextends Thread {

s t a t i c E n t i e r P a r t a g e v a r p a r t ;i n t i d ;

V a r i a b l e P a r t a g e e B S ( i n t i d ) {t h i s . i d = i d ;

}

p u b l i c v o i d run ( ) {w h i l e ( v a r p a r t . v a l e u r>=i d ){

a f f i c h e ( ” Avant ”+v a r p a r t ) ;v a r p a r t . decremente ( i d ) ;a f f i c h e ( ” Apr e s ”+v a r p a r t ) ;t r y { s l e e p ( 0 , 0 ) ;}catch ( I n t e r r u p t e d E x c e p t i o n e ){a f f i c h e ( ” I n t e r r o m p u ” ) ;

}}a f f i c h e ( ” Termine ( ”+v a r p a r t+” ) ” ) ;}

v o i d a f f i c h e ( S t r i n g s ){System . out . p r i n t l n (

Thread . c u r r e n t T h r e a d ( ) . getName ()+” : ”+s ) ;}

p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {i n t n = 3 , v a l =9;

v a r p a r t = new E n t i e r P a r t a g e ( v a l ) ;f o r ( i n t i =1; i<=n ; i ++)

new V a r i a b l e P a r t a g e e S ( i ) . s t a r t ( ) ;System . out . p r i n t l n ( ”Main : v a l e u r = ”+v a l ) ;System . out . p r i n t l n ( ”Main : I l y a”+n+” t h r e a d s , ”

+” l a r e g l e du j e u e s t chaque t h r e a d ne ” ) ;System . out . p r i n t l n ( ”Main : peut r e t i r e r qu ’ un”

+” nombre de p o i n t s e g a l e a son i d e n t i t e .\n” ) ;}

Arnaud Labourel, [email protected] Les threads en Java

Page 25: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

VariablePartageeBienSynchronized.javac l a s s E n t i e r P a r t a g e{

i n t v a l e u r ;

E n t i e r P a r t a g e ( i n t v a l e u r ){t h i s . v a l e u r = v a l e u r ;

}

s y n c h r o n i z e d v o i d decremente ( i n t dec ){v a l e u r −= dec ;

}

s y n c h r o n i z e d boolean t e s t e ( i n t v ){r e t u r n ( v a l e u r>=v ) ;

}

p u b l i c S t r i n g t o S t r i n g (){r e t u r n S t r i n g . v a l u e O f ( v a l e u r ) ;

}}

c l a s s V a r i a b l e P a r t a g e e B Sextends Thread {

s t a t i c E n t i e r P a r t a g e v a r p a r t ;i n t i d ;

V a r i a b l e P a r t a g e e B S ( i n t i d ) {t h i s . i d = i d ;

}

p u b l i c v o i d run ( ) {w h i l e ( v a r p a r t . t e s t e ( i d ) ){

a f f i c h e ( ” Avant ”+v a r p a r t ) ;v a r p a r t . decremente ( i d ) ;a f f i c h e ( ” Apr e s ”+v a r p a r t ) ;t r y { s l e e p ( 0 , 0 ) ;}catch ( I n t e r r u p t e d E x c e p t i o n e ){a f f i c h e ( ” I n t e r r o m p u ” ) ;

}}a f f i c h e ( ” Termine ( ”+v a r p a r t+” ) ” ) ;}

v o i d a f f i c h e ( S t r i n g s ){System . out . p r i n t l n (

Thread . c u r r e n t T h r e a d ( ) . getName ()+” : ”+s ) ;}

p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {i n t n = 3 , v a l =9;

v a r p a r t = new E n t i e r P a r t a g e ( v a l ) ;f o r ( i n t i =1; i<=n ; i ++)

new V a r i a b l e P a r t a g e e B S ( i ) . s t a r t ( ) ;System . out . p r i n t l n ( ”Main : v a l e u r = ”+v a l ) ;System . out . p r i n t l n ( ”Main : I l y a”+n+” t h r e a d s , ”

+” l a r e g l e du j e u e s t chaque t h r e a d ne ” ) ;System . out . p r i n t l n ( ”Main : peut r e t i r e r qu ’ un”

+” nombre de p o i n t s e g a l e a son i d e n t i t e .\n” ) ;}

Arnaud Labourel, [email protected] Les threads en Java

Page 26: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Problemes de Coexistence

L’existence de plusieurs activites au sein d’un memeenvironnement induit necessairement des problemes de

ordonnancement =⇒non-determinisme desexecutionspartage des donnees

visibilite des donneessynchronisation des actions sur ces donnees

Arnaud Labourel, [email protected] Les threads en Java

Page 27: Les threads en Javapageperso.lif.univ-mrs.fr/~arnaud.labourel/PPD/cours2.pdfLes threads en Java Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr Universit e de Provence 26

Conclusion ProvisoireLa programmation multi-thread est delicate :

non-determinisme,variables partagee et synchronisation,optimisations provoquant des comportementsparfois non intuitifs,portabilite vs utilisation des ressources natives,variations dans l’implementation des machinesvirtuelles,erreurs ne se revelant que sous hautes charges (ie enproduction)...

Methodologie particuliere a suivre en utilisant lesnombreuses primitives de synchronisation (apparuesdepuis la version 1.5).

Arnaud Labourel, [email protected] Les threads en Java