Développement d’applications réparties
Serveurs Multi-Threadés
Khaled Barbaria
[email protected]
Faculté des Sciences de Bizerte
GLSI3
2022
Serveurs Multi-Threadés 1 - 18 Khaled Barbaria
Plan
1 Threads et processus
2 Création des Threads en java
3 Synchronisation en java
4 Exemple de serveur multi-threadé en Java
Serveurs Multi-Threadés 2 - 18 Khaled Barbaria
Threads et Processus I
Processus
Un processus est un programme en cours d’exécution complet.
A son propre espace d’adressage.
L’OS assure :
La protection mémoire
L’accès au CPU de chacun des processus
Changement de contexte : mémoriser/restituer l’état du processus
processus arrêté/activé.
Serveurs Multi-Threadés 3 - 18 Khaled Barbaria
Threads et Processus II
Thread
Flot de contrôle au sein du processus
Pas de protection de ressources entre les Threads d’un seul
processus, le changement de contexte est beaucoup plus rapide
qu’entre les processus.
Le programmeur doit faire attention à la protection des ressources
partagées .
Serveurs Multi-Threadés 4 - 18 Khaled Barbaria
Threads et Processus III
Figure 1 – Processus mono et multi-threadés
Serveurs Multi-Threadés 5 - 18 Khaled Barbaria
Threads et Processus IV
Figure 2 – Organisations des Processus et des Threads
Serveurs Multi-Threadés 6 - 18 Khaled Barbaria
Exemple : jeu vidéo en réseau
Un seul processus .. trois threads
Un Thread pour l’affichage graphique
Un Thread pour l’interaction avec l’utilisateur (clavier, souris,
manette„ etc.)
Un Thread pour la communication avec les processus distants.
Serveurs Multi-Threadés 6 - 18 Khaled Barbaria
Discussion
Avantages
Plus facile à programmer : un thread par tâche concurrente
Pas besoin d’écouter simultanément sur plusieurs sources
d’évènements (on définit un thread par source)
Meilleures performances : partage des ressources, utilisation de
plusieurs CPU (en cas de disponibilité)
Inconvénients
Si le nombre de threads est important : problèmes de performances
Risque de corruption des données : cohérence des données
assurée par le programmeur
Risque d’inter-blocage
Serveurs Multi-Threadés 7 - 18 Khaled Barbaria
Création des Threads en java I
Deux méthodes
Étendre la classe java.lang.Thread
Java ne supporte pas l’héritage multiple, donc hériter de la classe
Thread empêche d’hériter des autres classes de l’application
Hériter de la classe Thread peut causer le coût excessif d’héritage
de cette classe
Implémenter l’interface java.lang.Runnable
Évite les problèmes de la première méthode
Plus léger, et donne lieu à un programme mieux structuré
Serveurs Multi-Threadés 7 - 18 Khaled Barbaria
Création des Threads en java II
Listing 1 – Héritage de la classe Thread
1 class Output extends Thread {
2 p r i v a t e S t r i n g msg ;
3 public Output ( S t r i n g m) { msg = m; }
4 public void run ( ) {
5 while ( t r u e ) {
6 try {
7 System . o u t . p r i n t l n ( msg ) ;
8 / / a t t e n t e pendant ( au moins ) 250 ms
9 sleep (250) ;
10 }
11 catch ( I n t e r r u p t e d E x c e p t i o n e ) { } } }
12 public s t a t i c void main ( S t r i n g [ ] args ) {
13 Output t h r 1 = new Output ( "A" ) ;
14 Output t h r 2 = new Output ( "B" ) ;
15 thr1 . s t a r t ( ) ; thr2 . st a r t ( ) ;
16 }
17 }
Serveurs Multi-Threadés 8 - 18 Khaled Barbaria
Création des Threads en java III
Listing 2 – Implémentation de la classe Runnable
1 class OutputR implements Runnable {
2 p r i v a t e S t r i n g msg ;
3 public OutputR ( S t r i n g m) { msg = m; }
4 public void run ( ) {
5 while ( t r u e ) {
6 try {
7 System . o u t . p r i n t l n ( msg ) ;
8 / / a t t e n t e pendant ( au moins ) 250 ms
9 Thread . s l e e p ( 2 5 0 ) ;
10 }
11 catch ( I n t e r r u p t e d E x c e p t i o n e ) { } } }
12 public s t a t i c void main ( S t r i n g [ ] args ) {
13 Thread t h r 1 = new Thread (new OutputR ( "A" ) ) ;
14 Thread t h r 2 = new Thread (new OutputR ( "B" ) ) ;
15 thr1 . s t a r t ( ) ; thr2 . st a r t ( ) ;
16 }
17 }
Serveurs Multi-Threadés 9 - 18 Khaled Barbaria
Création des Threads en java IV
Remarques générales
Le Thread du main thread n’est qu’un autre thread (qui
commence en premier)
Le Thread du main peut se terminer avant les autres
Tout thread peut lancer d’autres threads
L’appel de la méthode start déclare à la machine virtuelle que le
Thread peut commencer son exécution
L’appel de la méthode run ne crée pas de nouveau thread mais
exécute cette méthode dans le contexte du thread qui appelé run
Serveurs Multi-Threadés 10 - 18 Khaled Barbaria
Synchronisation en Java I
Verrous Java
À chaque object qui a du code (méthode, bloc ) synchronized
est associé un verrou
L’utilisation des verrous permet une exécution en exclusion
mutuelle
Le verrou est obtenu avant que le code du bloc (ou de la méthode)
synchronized ne soit exécuté.
Le verrou est relâche lors de la sortie du bloc.
Variables conditionnelles Java
La classe Object définit les méthodes wait(), notify(),
notifyAll()
Serveurs Multi-Threadés 11 - 18 Khaled Barbaria
Synchronisation en Java II
Listing 3 – sans synchronized
1 class Power {
2 void p r i n t P o w e r ( i n t n ) { / / method n o t s y n c h r o n i z e d
3 i n t temp = 1 ;
4 f o r ( i n t i =1; i <=5; i ++) {
5 System . o u t . p r i n t l n ( Thread . c u r r e n t T h r e a d ( ) . getName ( )
6 + " : − " +n + " ^ " + i + " v a l u e : " + n * temp ) ;
7 temp = n * temp ;
8 try {
9 Thread . s l e e p ( 1 0 0 ) ;
10 } catch ( E x c e p t i o n e ) { System . o u t . p r i n t l n ( e ) ; }
11 }
12 }
13 }
14
15 class Thread1 extends Thread {
16 Power p ;
17 Thread1 ( Power p ) {
18 t h i s . p=p ;
19 }
20 public void run ( ) {
21 p . printPower (5 ) ;
Serveurs Multi-Threadés 12 - 18 Khaled Barbaria
Synchronisation en Java III
22 }
23 }
24 class Thread2 extends Thread {
25 Power p ;
26 Thread2 ( Power p ) {
27 t h i s . p=p ;
28 }
29 public void run ( ) {
30 p . printPower (8 ) ;
31 }
32 }
33
34 public class SynchronizationExample {
35 public s t a t i c void main ( S t r i n g args [ ] ) {
36 Power o b j = new Power ( ) ; / / o n l y one o b j e c t
37 Thread1 p1=new Thread1 ( o b j ) ;
38 Thread2 p2=new Thread2 ( o b j ) ;
39 p1 . s t a r t ( ) ;
40 p2 . s t a r t ( ) ;
41 }
42 }
43
44
Serveurs Multi-Threadés 13 - 18 Khaled Barbaria
Synchronisation en Java IV
45 /*
46 Thread −1: − 8^1 value : 8
47 Thread −0: − 5^1 value : 5
48 Thread −0: − 5^2 value : 25
49 Thread −1: − 8^2 value : 64
50 Thread −0: − 5^3 value : 125
51 Thread −1: − 8^3 value : 512
52 Thread −0: − 5^4 value : 625
53 Thread −1: − 8^4 value : 4096
54 Thread −0: − 5^5 value : 3125
55 Thread −1: − 8^5 value : 32768
56 */
Serveurs Multi-Threadés 14 - 18 Khaled Barbaria
Synchronisation en Java V
Listing 4 – avec synchronized
1 public class SynchronizationExampleOK {
2 public s t a t i c void main ( S t r i n g args [ ] ) {
3 Power o b j = new Power ( ) ; / / o n l y one o b j e c t
4 Thread1 p1=new Thread1 ( o b j ) ;
5 Thread2 p2=new Thread2 ( o b j ) ;
6 p1 . s t a r t ( ) ;
7 p2 . s t a r t ( ) ;
8 }
9 }
10 /*
11 Thread −0: − 5^1 v a l u e : 5
12 Thread −0: − 5^2 v a l u e : 25
13 Thread −0: − 5^3 v a l u e : 125
14 Thread −0: − 5^4 v a l u e : 625
15 Thread −0: − 5^5 v a l u e : 3125
16 Thread −1: − 8^1 v a l u e : 8
17 Thread −1: − 8^2 v a l u e : 64
18 Thread −1: − 8^3 v a l u e : 512
19 Thread −1: − 8^4 v a l u e : 4096
20 Thread −1: − 8^5 v a l u e : 32768
21 */
Serveurs Multi-Threadés 15 - 18 Khaled Barbaria
Synchronisation en Java VI
Listing 5 – ”avec synchronized ; mais l’objet n’est pas partagé”
1 public class SynchronizationExample2 {
2 public s t a t i c void main ( S t r i n g args [ ] ) {
3 Thread1 p1=new Thread1 (new Power ( ) ) ;
4 Thread2 p2=new Thread2 (new Power ( ) ) ;
5 p1 . s t a r t ( ) ;
6 p2 . s t a r t ( ) ;
7 }
8 }
9 /*
10 Thread −0: − 5^1 v a l u e : 5
11 Thread −1: − 8^1 v a l u e : 8
12 Thread −1: − 8^2 v a l u e : 64
13 Thread −0: − 5^2 v a l u e : 25
14 Thread −0: − 5^3 v a l u e : 125
15 Thread −1: − 8^3 v a l u e : 512
16 Thread −0: − 5^4 v a l u e : 625
17 Thread −1: − 8^4 v a l u e : 4096
18 Thread −0: − 5^5 v a l u e : 3125
19 Thread −1: − 8^5 v a l u e : 32768
20 */
Serveurs Multi-Threadés 16 - 18 Khaled Barbaria
Exemple de serveur multi-threadé en Java I
1 import j a v a . n e t . * ; import j a v a . i o . * ; import j a v a . u t i l . * ;
2
3 class C l i e n t H a n d l e r implements Runnable {
4 p r i v a t e Socket c l i e n t S o c k e t = n u l l ;
5 p r i v a t e S t r i n g msg ;
6 public C l i e n t H a n d l e r ( Socket cs , S t r i n g m) {
7 t h i s . c l i e n t S o c k e t = cs ; msg=m;
8 }
9 public void run ( ) {
10 try {
11 OutputStream o u t p u t = c l i e n t S o c k e t . getOutputStream ( ) ;
12 S t r i n g t i m e = new Date ( ) . t o S t r i n g ( ) ;
13 o u t p u t . w r i t e ( ( "HTTP / 1 . 1 200 OK<H1> \ n \ nWorkerRunnable : "
+
14 t h i s . msg + " − " + t i m e + " <H1> " ) . g e t B y t e s ( ) ) ;
15 clientSocket . close ( ) ;
16 System . o u t . p r i n t l n ( " Request processed : " + t i m e ) ;
17 } catch ( IOException e ) {
18 e . printStackTrace ( ) ;
19 }
20 }
21 }
Serveurs Multi-Threadés 17 - 18 Khaled Barbaria
Exemple de serveur multi-threadé en Java II
1 public class M u l t i T h r e a d e d S e r v e r {
2 public s t a t i c void main ( S t r i n g args [ ] ) throws E x c e p t i o n {
3 ServerSocket ss = new ServerSocket ( 8 0 8 0 ) ;
4 while ( t r u e ) {
5 Socket c l i e n t S o c k e t =ss . accept ( ) ;
6 new Thread (new C l i e n t H a n d l e r ( c l i e n t S o c k e t ,
7 " M u l i t h r e a d e d Server ! " ) ) . s t a r t ( ) ;
8 }
9 }
10 }
Serveurs Multi-Threadés 18 - 18 Khaled Barbaria