Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs...

16
Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel CSC4509 — Utilisation des Threads Éric Lallet [email protected] Télécom SudParis 12 mai 2020 Éric Lallet[email protected] CSC4509 — Utilisation des Threads Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Lors du cours précédent nous avons vu que pour réussir à gérer plusieurs flux TCP sans être géné par les appels bloquants, il y avait deux solutions : Rendre les canaux non-bloquants et gérer les évènements avec la classe Selector de JAVA NIO; Utiliser plusieurs threads. La solution avec les Selectors a été vu lors du cours précédent. Ce cours présente la solution avec plusieurs threads (solution adaptée pour des serveurs comme ceux de FTP, HTTP. . . ) Éric Lallet[email protected] CSC4509 — Utilisation des Threads

Transcript of Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs...

Page 1: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

CSC4509 — Utilisation des Threads

Éric [email protected]

Télécom SudParis

12 mai 2020

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Lors du cours précédent nous avons vu que pour réussir à gérerplusieurs flux TCP sans être géné par les appels bloquants, il yavait deux solutions :

Rendre les canaux non-bloquants et gérer les évènements avecla classe Selector de JAVA NIO ;Utiliser plusieurs threads.

La solution avec les Selectors a été vu lors du cours précédent.Ce cours présente la solution avec plusieurs threads (solutionadaptée pour des serveurs comme ceux de FTP, HTTP. . . )

Éric [email protected] CSC4509 — Utilisation des Threads

Page 2: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Serveur multiclient : le problème

File

client 3

File

client 2

File

client 1

File nouveaux

clients

rwChan3.read()

rwChan2.read()

rwChan1.read()

lstChan.accept()

Client 3

rwChan.write()

Client 2

rwChan.write()

Client 1

rwChan.write()

Nouveaux

Clients

SocketChannel.open()

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Solution multithread : un thread par file

File

client 3

File

client 2

File

client 1

File nouveaux

clients

rwChan3.read()

rwChan2.read()

rwChan1.read()

lstChan.accept()

Client 3

rwChan.write()

Client 2

rwChan.write()

Client 1

rwChan.write()

Nouveaux

Clients

SocketChannel.open()

 

thread 1

thread 2

thread 3

m��� ���ead

Un thread par file

Éric [email protected] CSC4509 — Utilisation des Threads

Page 3: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Solution multiThread : gestion d’un nouveau client (1/4)

File

client 3

File

client 2

File

client 1

File nouveaux

clients

rwChan3.read()

rwChan2.read()

rwChan1.read()

n���n�� ��n����� ��

Client 3

rwChan.write()

Client 2

rwChan.write()

Client 1

rwChan.write()

Nouveaux

Clients

SocketChannel.open()

nv Client

rwChan.write()

File

nv client

nvChan.read()

thread 1

thread 2

thread 3

���� thread

Problème: deux �les pour le même thread

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Solution multiThread : gestion d’un nouveau client (2/4)

File

client 3

File

client 2

File

client 1

File nouveaux

clients

rwChan3.read()

rwChan2.read()

rwChan1.read()

Client 3

rwChan.write()

Client 2

rwChan.write()

Client 1

rwChan.write()

Nouveaux

Clients

SocketChannel.open()

nv Client

rwChan.write()

File

nv client

nvChan.read()

thread 1

thread 2

thread 3

���� ���ead

nv thread

!"#$ %&'("#$ )$**+,(-.créer nouveau thread

Nouveau thre�/ 01� ��h���h /e2 /e13 4les

Éric [email protected] CSC4509 — Utilisation des Threads

Page 4: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Solution multiThread : gestion d’un nouveau client (3/4)

File

client 3

File

client 2

File

client 1

File nouveaux

clients

rwChan3.read()

rwChan2.read()

rwChan1.read()

567895:;<=7895>9??@A=BCcré@D 5EF6@9F =8Dead

 

Client 3

rwChan.write()

Client 2

rwChan.write()

Client 1

rwChan.write()

Nouveaux

Clients

SocketChannel.open()

nv Client

rwChan.write()

File

nv client

nvChan.read()

 

thread 1

thread 2

thread 3

GHIJ KLMead

nv thread

Ne nouveau thrOHQ RSMO TJIUTOGOJKla Vle de lecture du nouveau client

NO GHIJ KLMOHQ JO RSMe plus la Vle

de lecture du dernier client arMIrSWXY MetourJO ZTM Y[HKKOJKO QO

Y[HllO\KHKI]J QO J]TrOHT^ lYIOJKZW

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Solution multiThread : gestion d’un nouveau client (4/4)

File

client 3

File

client 2

File

client 1

File nouveaux

clients

rwChan3.read()

rwChan2.read()

rwChan1.read()

lstChan.accept()

Client 3

rwChan.write()

Client 2

rwChan.write()

Client 1

rwChan.write()

Nouveaux

Clients

SocketChannel.open()

Client _

rwChan.write()

File

c`abdf g

ijkopdgqiead()

thread 1

thread 2

thread 3

thrbps g

tpad foiead

À duvwbpv vd foiead par xle

Éric [email protected] CSC4509 — Utilisation des Threads

Page 5: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Threads JAVA

Il existe plusieurs solutions pour qu’une classe JAVA puisse êtreutilisée pour créer un thread :

1 Hériter de la classe Thread ;2 Implémenter l’interface Runnable ;3 Implémenter l’interface Callable<V>.

Pour les deux premières solutions la classe doit définir une méthodepublic void run(). Pour la troisième elle doit définir une méthodepublic V call(), et le thread appelant doit utiliser une instance del’interface Future<V> pour la réception du résultat.Ce cours expose les solutions 2 et 3.

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Threads JAVA : Runnable versus Callable<V>

La méthode void run() de l’interface Runnable n’a pas derésultat et ne transmet les exceptions. S’il faut transmettre cesinformations à un autre thread, il faut ajouter des référencescommunes qui compliquent la programmation ;La méthode public V call() fournit un résultat et saittransmettre les exceptions. Un simple appel à la méthodepublic V get() de l’interface Future<V> permet à un autrethread de les connaître.

Pour un thread qui doit continuer sa vie sans chercher à partagerd’informations avec les autres threads, l’interface Runnable seraplus simple à mettre en œuvre, et sinon il faudra plutôt choisirl’interface Callable<V>.

Éric [email protected] CSC4509 — Utilisation des Threads

Page 6: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Threads JAVA avec l’interface Runnable

Avec l’interface Runnable, pour créer un nouveau thread en JAVA,il faut :

Écrire une classe qui implémente l’interface Runnable ;Créer une instance de cette classe ;Créer une instance de la classe Thread en passant la référencede la classe Runnable en paramètre du constructeur ;Appeler la méthode start() de l’instance de Thread.

La méthode start() de Thread va démarrer le nouveau thread endémarrant la méthode run() de la classe Runnable

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Threads JAVA avec l’interface Runnable

Exemple d’usage :MaClasseRunnable monRunnable ; // une c l a s s e Runnable

monRunnable=new MaClasseRunnable ( ) ; //une i n s t a n c e de c e t t e c l a s s e

Thread th r ead = new Thread (monRunnable ) ; // une i n s t a n c e de Thread

th r ead . s t a r t ( ) ; // l a mé thode run ( ) s ’ ex é cu te ␣ dans ␣ l e ␣ th r ead

La plupart du temps, les variables qui contiennent les références del’exemple ci-dessus ne servent plus. Donc, généralement on résumeces quatre étapes en une seule ligne :

new Thread (new MaClasseRunnable ( ) ) . s t a r t ( ) ;

Éric [email protected] CSC4509 — Utilisation des Threads

Note : L’interface Runnable est une interface fonctionnelle, donc le paramètre du constructeurdu Thread peut être une expression lambda. Par exemple, si on souhaite exécuter une méthodesimple() sans paramètre dans un nouveau thread on peut écrire le code :new Thread( () -> simple() ).start() ;

Page 7: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Threads JAVA avec l’interface Callable<V>

Avec l’interface Callable<V>, pour créer un nouveau thread enJAVA, il faut :

Écrire une classe qui implémente l’interface Callable<V> ;Créer une instance de cette classe ;Créer un instance d’un classe qui implémente Future<V> (parexemple la classe FutureTask<V>) en passant la référence dela classe Callable<V> en paramètre du constructeur ;Créer une instance de la classe Thread en passant la référencede la classe Future<V> en paramètre du constructeur ;Appeler la méthode start() de l’instance de Thread ;Récupérer le résultat de la méthode V call() par un appel de laméthode V get() de Future<V>.

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Threads JAVA avec l’interface Callable<V>

MaClasseCallable<V> maTache; // une classe Callable<V>

// création d’une instance de la la classe MaClasseCallablemaTache = new MaClasseCallable<V>();

// création d’une instance de la classe FutureFutureTask<V> future = new FutureTask<V>(maTache);

// création d’une instance de la classe ThreadThread thread = new Thread(future);

// démarage du threadthread.start(); // la méthode V call() s’exécute dans le thread

// récupération du résultat: par défaut get() bloque// en attendant la fin du thread.V result = future.get():

Éric [email protected] CSC4509 — Utilisation des Threads

Note 1 : Il n’est pas possible de créer un tableau de classes paramétrées. Il faut créer un tableaude la classe sans paramétre :FutureTask<V> [] mesTachesFutures = new FutureTask[SIZE] ; // cause un warningUne façon plus propre de répondre à ce besoin consiste à utiliser une Collection :List< FutureTask<V> > mesTachesFutures = new ArrayList< FutureTask<V> >() ;Note 2 : Il existe une version de get avec un timeout. Par exemple, si vous voulez attendre 20secondes au plus, il faut écrire :V result = future.get(20, TimeUnit.SECONDS) :

Si le thread n’est pas fini au bout de 20 secondes, l’exception TimeoutException est levée.

Page 8: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Accès concurrentiel : le problème

L’accès à la mémoire d’un thread peut être partagé :Un thread peut avoir des références sur des objets ou destableaux utilisés par d’autres threads ;Un autre thread peut modifier une de vos ressources enpassant par les méthodes d’accès publiques ;. . .

L’accès concurrentiel à une ressource commune va de paire avec lagestion de sections critiques et une politique d’exclusion mutuelle

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Accès concurrentiel : les solutions

JAVA fournit de nombreuses solutions pour mettre en œuvre unepolitique d’exclusion mutuelle :

La classe Lock ;La classe Semaphore ;Les blocs synchronisés ;. . .

Dans ce cours, nous abordons les blocs synchronisés

Éric [email protected] CSC4509 — Utilisation des Threads

Page 9: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Blocs synchronisés

Il existe trois procédés pour gérer une section critique avec les blocssynchronisés.

1 Soit on synchronise sur un objet explicite2 Soit on synchronise une méthode d’instance3 Soit on synchronise une méthode de classe

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Blocs synchronisés : sur un objet explicite

Pour synchroniser un bloc avec un objet explicite, il faut :Avoir une référence sur un objet qui sera partagée par lesdifférents threads que vous voulez synchroniserPar exemple : Ressource maRessource ;Utiliser les instructions suivantes :

s y n ch r on i z e d ( maRessource ) {// i c i l e s i n s t r u c t i o n s p ro t égé es

}

Lorsqu’un thread entre dans le bloc synchronisé, les autresthreads qui veulent entrer dans un bloc synchronisé sur lemême objet vont être bloqués jusqu’à ce que le premierthread quitte le bloc synchroniséDit autrement, un seul thread pourra être en train d’exécuterdes instructions d’un quelconque bloc synchronisé sur unemême référence.

Éric [email protected] CSC4509 — Utilisation des Threads

Page 10: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Bloc synchronisés : sur une ressource

yz{|}~ ~|��� ��������� }�y|������ �z���{|� �

private Ressource maRessour~��

yz{|}~ ������ead(Ressource maRessour~�� �

this.maRessour~� � ���essour~��

}

@Override

yz{|}~ ��}� �z��� �

}�� ��|�� ��|��

��}|� ���z�� �

��� �

��|� � ���essour~�������|���

maRessour~��~�����������

��|� � ���essour~�������|���

������ ��|� �� ���|� �� ��

� ~��~� �������zy�����~�y�}�� �� �

��y�}�����~ ���~����

}}

}}

public class Ressour~� �

y�}���� }�� ��| � ¡�

public Ressource(¢��| }�� ��|� �

this.val � ��|�

}

yz{|}~ }�� �����|�� �

retur� ��|�

}

yz{|}~ ��}� ~����������

thr��� ������zy�����~�y�}�� �

}�� ����| � ��|�

��������|��y�£¡¡¡��

����|���

��| � ����|�

}}

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Blocs synchronisés : sur une ressource

¤¥¦§¨© ©§ª«« ¬­®¯°±²ª³ ¨´¤§²´²®µ« ¶¥®®ª¦§² ·

private Ressource maRessour©²¸

¤¥¦§¨© ¬­®¯°±ead(Ressource maRessour©²¹ ·

this.maRessour©² º ´ª¶essour©²¸

}

@Override

¤¥¦§¨© »­¨³ ±¥®¼¹ ·

¨®µ »ª§½¾ »ª§¿¸

Á°¨§² ¼µ±¥²¹ ·

µ±Â ·

«Â®©°±­®¨Ã²³ ¼´ª¶essour©²¹ ·

»ª§½ º ´ª¶essour©²ÄŲµÆª§¼¹¸

maRessour©²Ä©­®«­´´²±¼¹¸

»ª§¿ º ´ª¶essour©²ÄŲµÆª§¼¹¸

}

ª««²±µ »ª§¿ ºº ¼»ª§½ ǽ ¹¸

È ©ªµ©° ¼É®µ²±±¥¤µ²³ÊË©²¤µ¨­® ²¹ ·

²Ä¤±¨®µÌµª©Í ±̄ª©²¼¹¸

}}

}}

public class Ressour©² ·

¤±¨»ªµ² ¨®µ »ª§ º θ

public Ressource(Ï®ª§ ¨®µ »ª§¹ ·

this.val º »ª§¸

}

¤¥¦§¨© ¨®µ ŲµÆª§¼¹ ·

retur® »ª§¸

}

¤¥¦§¨© »­¨³ ©­®«­´´²±¼¹

thr­Á« É®µ²±±¥¤µ²³ÊË©²¤µ¨­® ·

¨®µ ´ªÆª§ º »ª§¸

¯°±²ª³Ä«§²²¤¼ÐÎÎι¸

´ªÆª§ÇǸ

»ª§ º ´ªÆª§¸

}}

Éric [email protected] CSC4509 — Utilisation des Threads

Page 11: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Blocs synchronisés : sur la référence this

La référence utilisée pour synchroniser un bloc peut être this

s y n c h r o n i z e d ( t h i s ) {// i c i l e s i n s t r u c t i o n s p r o t égé es

}

Tous les threads qui utilisent une méthode de l’objet bloquerontsur les blocs synchronisés par this si un autre thread est déjàdans un de ces blocs là

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Blocs synchronisés : sur la référence this

ÑÒÓÔÕÖ ÖÔ×ØØ ÙÚÛÜÝÞß×à ÕáÑÔßáßÛâØ ãÒÛÛ×ÓÔß ä

private Ressource maRessourÖßå

ÑÒÓÔÕÖ ÙÚÛÜÝÞead(Ressource maRessourÖßæ ä

this.maRessourÖß ç á×ãessourÖßå

}

@OverrideÑÒÓÔÕÖ èÚÕà ÞÒÛêæ ä

âÞë ä

ìÝÕÔß êâÞÒßæ ä

maRessourÖßíÖÝ×ÛîßÞêæå

assert maRessourÖßíîßâï×Ôêæ ðç ñå

}

ò Ö×âÖÝ êóÛâßÞÞÒÑâßàôõÖßÑâÕÚÛ ßæ ä

ßíÑÞÕÛâöâ×Ö÷ÜÞ×Ößêæå

}}}

public class RessourÖß ä

ÑÞÕè×âß ÕÛâ è×Ô ç øùå

public Ressource(úÛ×Ô ÕÛâ è×Ôæ ä

âÝÕØíè×Ô ç è×Ôå

}

ÑÒÓÔÕÖ ÕÛâ îßâï×Ôêæ ä

returÛ è×Ôå

}

ÑÒÓÔÕÖ èÚÕà ÖÝ×ÛîßÞêæ

thrÚìØ óÛâßÞÞÒÑâßàôõÖßÑâÕÚÛ ä

Õû êè×Ô ðç øñæ ä

ÜÝÞß×àíØÔßßÑê ùñññæå

è×Ô üç øñå

}ßÔØß ä

ÜÝÞß×àíØÔßßÑê ùñññæå

è×Ô ýç þñå

}

}}

Éric [email protected] CSC4509 — Utilisation des Threads

Page 12: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Blocs synchronisés : sur la référence this

ÿp���� ����� ����e�� � ÿ�e e��� �p�����e u

private Ressource maRessour�ec

ÿp���� ����ead(Ressource maRessour�e� u this.maRessour�e � ��essour�ec}

@Overrideÿp���� ���� �p��� u

�� u

���e ���pe� u

maRessour�e�����e���c assert maRessour�e��e������ a� �c

}

} ���� ����e��pÿ�e�r��eÿ���� e� u

e�ÿ������������e��c

}}}

public class Ressour�e u

ÿ�����e ��� ��� � ��c

public Ressource(���� ��� ���� u������� � ���c

}

ÿp���� ��� �e������ u

retur� ���c

}

ÿp���� ���� ����e���

thr��� ���e��pÿ�e�r��eÿ���� u

� ������oe������ u

�! ���� a� ��� u

�e�����eeÿ� �����c

��� "� ��c

}e��e u

�e�����eeÿ� �����c

��� #� $�c

} }}}

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Blocs synchronisés : sur une méthode d’instance

Sur l’exemple précédent toutes les instructions de la méthode sontdans le bloc synchronisé sur this. Il y a alors une autre syntaxepour signifier la même chose :

p u b l i c s y n c h r o n i z e d vo i d maMethode ( )

// t o u t e s l e s i n s t r u c t i o n s de l a// mé thode son t p r o t égé es

}

Éric [email protected] CSC4509 — Utilisation des Threads

Page 13: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Sections synchronisées : sur une méthode d’instance

%&'()* *(+,, -./0123+4 )5%(353/6, 7&//+'(3 8

private Ressource maRessour*39

%&'()* -./012ead(Ressource maRessour*3: 8 this.maRessour*3 ; 5+7essour*39}

@Override%&'()* <.)4 2&/=: 8

62> 8

?1)(3 =62&3: 8

maRessour*3@*1+/A32=:9 assert maRessour*3@A36B+(=: C; D9

}E *+6*1 =F/6322&%634GH*3%6)./ 3: 8

3@%2)/6I6+*J02+*3=:9

}}}

public class Ressour*3 8

%2)<+63 )/6 <+( ; KL9

public Ressource(M/+( )/6 <+(: 861),@<+( ; <+(9

}

%&'()* )/6 A36B+(=: 8

retur/ <+(9

}

%&'()* ,>/*12./)N34 <.)4 *1+/A32=:

thr.?, F/6322&%634GH*3%6)./ 8

)i =<+( C; KD: 8

0123+4@,(33%= LDDD:9

<+( O; KD9

}3(,3 8

0123+4@,(33%= LDDD:9

<+( P; QD9

}}}

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Sections synchronisées : sur une méthode de classe

Il est aussi possible de synchroniser une méthode de classe. Dans cecas, la référence this n’existe pasLa synchronisation se fait sur la référence MaRessource.class :c l a s s MaRessource {( . . . )s t a t i c p u b l i c s y n ch r on i z e d vo i d maMethode ( )

// t o u t e s l e s i n s t r u c t i o n s de l a// mé thode son t p ro t égé es

}}

Dans ce cas, si cette méthode est exécutée par un thread, tous lesautres thread tenteront d’appeler une méthode de classesynchronisée de cette classe seront bloqués.

Éric [email protected] CSC4509 — Utilisation des Threads

Page 14: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Synchronisation des threads

Il est parfois utile qu’un thread soit bloqué en attente d’un autre :attendre qu’un objet soit construit par un autre thread pourl’utiliser ;attendre qu’une ressource soit produite par un autre threadpour la consommer ;attendre la fin d’un autre thread.

Il existe des méthodes pour faire ces synchronisations : wait(),notify(), notifyAll(), join().

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Synchronisation des threads

Les méthodes wait(), notify() et notifyAll() sont héritées de laclasse Object et sont donc implémentées pour toutes les classes.Elles ne peuvent être appelées que sur un objet d’un blocsynchronisé.

public void methode1() {synchronized(maRessource) { // obligatoire pour

(...) // l’usage de wait()maRessource.wait();(...)

}}public void methode2() {synchronized(maRessource) { // obligatoire pour

(...) // l’usage de notify()maRessource.notify();(...)

}}

Éric [email protected] CSC4509 — Utilisation des Threads

Note1 : Version avec un synchronized sur une méthode d’instance :

public synchronized void methode1() {(...)wait();(...)

}public synchronized void methode2() {

(...)notify();(...)

}

Page 15: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Synchronisation des threads

wait() est bloquant jusqu’à ce qu’un autre thread appellenotify() ou notifyAll() sur le même objet ;l’attente de wait() est équivalent à une sortie du blocsynchronisé ;le réveil de wait() est équivalent à une entrée dans le blocsynchronisé ;si plusieurs threads bloquent sur un wait() sur le même objet,un appel de notify() ne réveillera qu’un seul d’entre-eux ;notifyAll() reveillent tous les wait() associés ;wait(long timeout) permet de fixer un délais maximal d’attente(en milliseconde).

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Synchronisation des threads

p r i v a t e Queue<I n t e g e r > maFi l e ;

p u b l i c vo i d p r o d u i r e ( i n t v a l ) {s y n ch r on i z e d ( maFi l e ) {

maFi l e . add ( v a l ) ;maF i l e . n o t i f y ( ) ;

}}p u b l i c I n t e g e r consommer ( ) {

s y n ch r on i z e d ( maFi l e ) {whi le ( maF i l e . s i z e ( ) == 0) {

t r y {maFi l e . wa i t ( ) ;

} ca tch ( I n t e r r u p t e dE x c e p t i o n e ) {}}I n t e g e r r e s = maFi l e . p o l l ( ) ;re tu rn r e s ;

}}

Éric [email protected] CSC4509 — Utilisation des Threads

Page 16: Lors du cours précédent nous avons vu que pour réussir à ...Introduction Solution avec plusieurs threads Threads JAVA Accès concurrentiel Solution multiThread : gestion d'un nouveau

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

Synchronisation des threads

join() est une méthode de la classe Thread. Elle permet debloquer en attendant la fin du trhead ;Il est possible de donner un délais maximal d’attente avec laméthode join(long timeout). Le timeout est exprimé enmilliseconde ;Notez que pour les threads Callable, la méthode get() del’interface Future fonctionne sur le même principe.

Éric [email protected] CSC4509 — Utilisation des Threads

IntroductionSolution avec plusieurs threads

Threads JAVAAccès concurrentiel

p u b l i c c l a s s ExempleJo in {p r i v a t e s t a t i c f i n a l i n t MAX = 5 ;

p u b l i c ExempleJo in ( ) throws I n t e r r u p t e dE x c e p t i o n {Thread [ ] t a ch e s = new Thread [MAX] ;f o r ( i n t i nd = 0 ; i nd < 5 ; i nd++) {

i n t d e l a i s = ind ;t a ch e s [ i nd ] = new Thread ( ( ) −> exemple ( d e l a i s ) ) ;t a ch e s [ i nd ] . s t a r t ( ) ;

}f o r ( i n t i nd = 0 ; i nd < 5 ; i nd++) {

t a che s [ i nd ] . j o i n ( ) ;}System . out . p r i n t l n ( "Tous␣ l e s ␣ t h r e ad s ␣ son t ␣ t e rm in é s " ) ;

}p u b l i c vo i d exemple ( i n t d e l a i s ) {

System . out . p r i n t l n ( d e l a i s + "␣dé bute . " ) ;t r y {

Thread . s l e e p ( d e l a i s ∗ 1000) ;} ca tch ( I n t e r r u p t e dE x c e p t i o n e ) { }System . out . p r i n t l n ( d e l a i s + "␣ t e rm ine . " ) ;

}}

Éric [email protected] CSC4509 — Utilisation des Threads

Note1 : Dans l’expression lambda qui implémente la méthode run() duthread, la méthode exemple() reçoit un paramètre. Il n’est pas possible depasser la variable de boucle ind pour fixer la valeur de ce paramètre. Il estpossible d’utiliser une variable du contexte englobant dans une expressionlambda à condition que cette variable soit finale ou effectivementfinale. Ici la variable de boucle ind est incrémentée à chaque tour. Elle nerépond pas à la condition. Pour résoudre ce problème, il suffit de recréer àchaque tour une nouvelle variable (ici la variable delais) qui recopie cettevaleur.