Vous êtes sur la page 1sur 41

Cours de Java Avancé

Les fils d'exécution (Thread) en Java

ES-SALHI Rachida
rachida.es-salhi@ensem.ac.ma

Ecole Marocaine des sciences de l’ingénieur


Muti-tâches

 Multi-tâches : exécution de plusieurs processus simultanément.


 Un programme est concurrent, ou multitâches, quand il lance (ou
peut lancer) l’exécution de plusieurs parties de son code en
même temps;
 Dans la programmation concurrente, il existe principalement deux
unités d'exécution : les processus et les threads.
 Tous les systèmes d’exploitation modernes sont multitâches, ils
exécutent en même temps plusieurs programmes (plusieurs
processus).
 L'exécution des processus et des threads est gérée par l'OS

ES-SALHI| Java Avancé : Les Threads


Processus

 Un processus possède son propre environnement d'exécution


(ressources systèmes) ;
 Chaque processus a son propre espace mémoire (espace où sont
rangées les valeurs des variables utilisées par le processus);
 Un processus peut lancer plusieurs threads qui partagent le
même espace mémoire ; ils peuvent accéder aux mêmes
variables;
 Un processus peut être dans différents états.
– En exécution (running) : il utilise le processeur
– Prêt : le processus est prêt à s'exécuter, mais n'a pas le
processeur (occupé par un autre processus en exécution)
– Bloqué

ES-SALHI| Java Avancé : Les Threads


Qu'est ce qu'un thread?

 Java est un langage multi-threads


 Il permet d’exécuter plusieurs blocs d’instructions à la fois.
 Chaque bloc est appelé Thread ’processus léger’.
 Les threads nécessitent moins de ressources : ils partagent les
ressources du processus père: mémoire, fichiers ouverts, etc.
Exemple:
Le serveur réseau qui
attend les demandes
de connexions venant
des autres machines
lance un thread pour
traiter chacune des
demandes;

ES-SALHI| Java Avancé : Les Threads


Thread en Java

A tout thread, Java associe:


- un objet qui détermine le code à exécuter par le thread;
- un objet qui « contrôle » le thread et le représente auprès
des objets de l’application ; on l’appellera le « contrôleur
de thread ».
En Java, il existe, deux techniques pour créer un
thread:
Soit vous dérivez votre thread de la classe:
java.lang.Thread,
soit vous implémentez l'interface:
java.lang.Runnable.
ES-SALHI| Java Avancé : Les Threads
Créer un thread en dérivant de la classe java.lang.Thread.

ES-SALHI| Java Avancé : Les Threads


Exemple de classe héritant de Thread

ES-SALHI| Java Avancé : Les Threads


Créer un thread en implémentant l'interface java.lang.Runnable.

ES-SALHI| Java Avancé : Les Threads


Exemple de classe implémentant Runnable

ES-SALHI| Java Avancé : Les Threads


Quelle technique choisir ?

ES-SALHI| Java Avancé : Les Threads


Gestion des threads

 Cycle de vie d'un thread

Thread.currentThread().getState() retourne l’état courant du thread


ES-SALHI| Java Avancé : Les Threads
Démarrage, suspension, reprise et arrêt d'un thread

public void start() : cette méthode permet de démarrer un thread. En effet, si


vous invoquez la méthode run (au lieu de start) le code s'exécute bien, mais aucun
nouveau thread n'est lancé dans le système. Inversement, la méthode start, lance
un nouveau thread dans le système dont le code à exécuter démarre par le run.

public void suspend() : cette méthode permet d'arrêter temporairement un


thread en cours d'exécution.

public void resume() : celle-ci permet de relancer l'exécution d'un thread, au


préalable mis en pause via suspend. Attention, le thread ne reprend pas au début
du run, mais continue bien là où il s'était arrêté.

public void stop() : cette dernière méthode permet de mettre fin, de manière
définitive, à l'exécution du thread. Une autre solution pour stopper un thread
consiste à simplement sortir de la méthode run.

ES-SALHI| Java Avancé : Les Threads


Gestion de la priorité d'un thread.
Utilisation d'une boucle pour définir les valeurs:
Vous pouvez, en Java, jouer sur la priorité de vos threads.
Sur une durée déterminée, un thread ayant une priorité plus haute recevra
plus fréquemment le processeur qu'un autre thread. Il exécutera donc,
globalement, plus de code.
La priorité d'un thread va pouvoir varier entre 0 et 10. Mais attention, il n'est
en a aucun cas garanti que le système hôte saura gérer autant de niveaux de
priorités.
 Des constantes existent et permettent d'accéder à certains niveaux de
priorités : MIN_PRIORITY (0) - NORM_PRIORITY (5) -
MAX_PRIORITY (10).
Pour spécifier la priorité d’un thread, il faut faire appel à la méthode
setPriority(int p) de la classe Thread
 Exemple :
Thread t=new Thread();
 t.setPriority(Thread.MAX_PIORITY);
ES-SALHI| Java Avancé : Les Threads
Synchronisation de threads et accès aux ressources partagées.

Lorsque que vous lancez une JVM (Machine Virtuelle Java),


vous lancez un processus.
Ce processus possède plusieurs threads et chacun d'entre eux
partage le même espace mémoire.
 En effet, l'espace mémoire est propre au processus et non à un
thread.
Cette caractéristique est à la fois un atout et une contrainte.
 En effet, partager des données pour plusieurs threads est
relativement simple.
 Par contre les choses peuvent se compliquer sérieusement si la
ressource (les données) partagée est accédée en modification
il faut synchroniser les accès concurrents. Nous sommes
certainement face à l'un des problèmes informatiques les plus
délicats à résoudre.
ES-SALHI| Java Avancé : Les Threads
Synchronisation de threads et accès aux ressources partagées.

 Soit l’exemple suivant:

ES-SALHI| Java Avancé : Les Threads


Synchronisation de threads et accès aux ressources partagées.

Imaginez qu'un premier thread évalue l'expression


MaClasse.Compteur + 1 mais que le système lui hôte le cpu,
juste avant l'affectation, au profit d'un second thread.
 Ce dernier se doit lui aussi d'évaluer la même expression.
Le système redonne la main au premier thread qui finalise
l'instruction en effectuant l'affectation, puis le second en fait
de même.
Au final de ce scénario, l'entier aura été incrémenté que
d'une seule et unique unité.
De tels scénarios peuvent amener à des comportements
d'applications chaotiques. Il est donc vital d'avoir à notre
disposition des mécanismes de synchronisation.
ES-SALHI| Java Avancé : Les Threads
Notions de verrous
 L'environnement Java offre un premier mécanisme de synchronisation : les
verrous (locks en anglais).
 Chaque objet Java possède un verrou et seul un thread à la fois peut verrouiller un
objet.
 Si d'autres threads cherchent à verrouiller le même objet, ils seront endormis
jusqu'à que l'objet soit déverrouillé.
 Cela permet de mettre en place ce que l'on appelle plus communément une
section critique.
 Pour verrouiller un objet par un thread, il faut utiliser le mot clé synchronized.
 En fait, il y a deux façons de définir une section critique. Soit on synchronise un
ensemble d'instructions sur un objet, soit on synchronise directement l'exécution
d'une méthode pour une classe donnée.
 Dans le premier cas, on utilise l'instruction synchronized : synchronized(object)
{ //Instructions de manipulation d'une ressource partagée}
 Dans le second cas, on utilise le qualificateur synchronized sur la méthode
considérée:
public synchronized void meth(int param) { // Le code de la méthode
synchronizée}
ES-SALHI| Java Avancé : Les Threads
Exemple : Synchroniser les threads au moment de
l’incrémentation de la variable compteur

ES-SALHI| Java Avancé : Les Threads


Exemple : Synchroniser les threads avant l’accès à la méthode run

ES-SALHI| Java Avancé : Les Threads


Méthodes de la classe Thread

 static int activeCont(): renvoie le nombre de threads actuellement


exécutés
 static Thread currentThread() : renvoie le thread en cours
d’execution.
 static void yield() : provoque une « pause » du thread en cours
d’execution et un réordonnacement.
Manipulation de threads. Quelques méthodes provoquent:
 La mise en attente : void sleep(long mills)
 L’attente de l’arrêt d’un autre thread: void join() ou void join(long
mills) avec délai.
 L’intteruption d’un thread: void interrupt().

ES-SALHI| Java Avancé : Les Threads


Attente et notification des threads
Il existe trois méthodes qui permettent la communication entre les threads:
public void wait() : mets en attente un thread en cours d’exécution
public void notify ()/ notifyAll(): :servent à interrompre cette attente

Ramarque : Ce sont des méthodes de la classe Object pas de la classe Thread


La méthode wait() doit être invoquée à l'intérieur d'une méthode ou d'un bloc
synchronisé sur l'objet concerné. Typiquement, on pourra écrire :

Pour réveiller un thread qui attend:

Si plusieurs threads ont été mis en attente par unObjet, l'instruction notify() invoquée


par unObjet réveille l'un d'entre eux de façon arbitraire. Pour réveiller tous les threads
bloqués par unObjet, il faut remplacer notify() par notifyAll(). 

ES-SALHI| Java Avancé : Les Threads


Attente et notification des threads
 Soit un programme qui gère une "réserve". Il comporte :
• un thread qui ajoute une quantité donnée,
• deux threads qui puisent chacun une quantité donnée.
Un thread ne peut puiser dans la réserve que si elle contient une
quantité suffisante.
 La réserve est représentée par un objet r, de type Reserve. Cette
classe dispose de deux méthodes synchronisées puise et ajoute.
Lorsque la méthode puise s’aperçoit que la réserve est
insuffisante, il appelle wait pour mettre le thread correspondant
en attente. Parallèlement, la méthode ajoute appelle notifyAll
après chaque ajout.

ES-SALHI| Java Avancé : JDBC


Utilisation de wait() et notifyAll()
La classe Reserve Le thread puiseur

Le thread d’ajout
La classe contenant main
Exemple QCM
 Soit le fragment de code suivant:
1. public class Fabric extends Thread {
2. public static void main(String[] args) {
3. Thread t = new Thread(new Fabric());
4. Thread t2 = new Thread(new Fabric());
5. t.start();
6. t2.start();
7. }
8. public static void run() {
9. for(int i = 0; i < 2; i++)
10. System.out.print(Thread.currentThread().getName() + " ");
11. }
12. }
Quelle réponse est correcte?
A. La compilation échoue.
B. Aucun affichage.
C. La sortie peut être Thread-1 Thread-3 Thread-1 Thread-2
D. La sortie peut être Thread-1 Thread-3 Thread-1 Thread-3
E. La sortie peut être Thread-1 Thread-1 Thread-2 Thread-2
F. La sortie peut être Thread-1 Thread-3 Thread-3 Thread-1
G. La sortie peut être Thread-1 Thread-3 Thread-1 Thread-1

ES-SALHI| Java Avancé : JDBC


Les Threads
 Un thread est une unité d'exécution faisant partie d'un programme.
 Cette unité fonctionne de façon autonome et parallèlement à d'autres
threads.
 Le principal avantage des threads est de pouvoir répartir différents
traitements d'un même programme en plusieurs unités distinctes pour
permettre leurs exécutions "simultanées".
 La classe java.lang.Thread et l'interface java.lang.Runnable sont les
bases pour le développement des threads en java.

ES-SALHI| Java Avancé : JDBC


Exercice
 Créer une application graphique SWING qui permet de créer des objets de type Voiture.
 Chaque voiture, ayant un nom et un compteur, est représenté par un thread qui permet de
d’incrémenter 100000 fois le compteur avec une petite temporisation. Le thread créé
utilise la priorité sélectionnée.
 Chaque voiture est représenté graphiquement par une étiquettes qui affiche le nom et le
compteur de la voiture et un bouton qui permet de suspendre ou de réactiver le thread.
 Prévoir un compteur global à toutes les voitures qui sera incrémenté par tous les threads
pour chaque itération.
 Remarquez que la valeur final du compteur global est fausse. Pour 6 voitures elle devrait
être normalement égale à : 600000.
 Corriger le problème en utilisant la synchronisation des threads.

ES-SALHI| Java Avancé : JDBC


Exercice

 Cas non
synchronisé

 Cas
synchronisé

ES-SALHI| Java Avancé : JDBC


Correction : La Classe Voiture

ES-SALHI| Java Avancé : JDBC


Suite Classe Voiture
public void rouler(){
for(int i=0;i<COMPTEUR_MAX;i++){
++compteur;
synchronized (this.getClass()) {
++compteurGlobal;
}
jProgressBar.setValue(compteur);
jLabelCompteur.setText(String.valueOf(compteur));
Thread.yield();
}
}
@Override
public void run() { rouler(); }
public Thread getThread() { return thread; }
public void setThread(Thread thread) { this.thread = thread; }

ES-SALHI| Java Avancé : JDBC


Classe CourseGUI

ES-SALHI| Java Avancé : JDBC


suite de Classe CourseGui

ES-SALHI| Java Avancé : JDBC


Programmation réseau

Les Sockets Java


Application distribuées

TCP/IP ou
Machine 1 UDP Machine 2

Application 2
Application 1

Technologies d’accès :
• Sockets ou DataGram
• RMI (JAVA)
• CORBA (Multi Langages)
• EJB (J2EE)
• Web Services (HTTP+XML)

ES-SALHI| Java Avancé


Principe de base
Création d’un client Création d’un serveur

xio n
n n e
Co

write read
os is
read write
is os
ES-SALHI| Java Avancé
Exemple d’un serveur simple
import java.io.*;import java.net.*;
public class Serveur {
public static void main(String[] args) {
try {
ServerSocket ss=new ServerSocket(1234);
System.out.println("j'attend la connexion d'un client");
Socket clientSocket=ss.accept();
System.out.println ("Nouveau client connecté");
System.out.println("Génération de objet InptStream et
OutputStream de la socket");
InputStream is=clientSocket.getInputStream();
OutputStream os=clientSocket.getOutputStream();
System.out.println("J'attend un nombre (1 octet)!");
int nb=is.read();
System.out.println("J'envoie la réponse");
os.write(nb*5);
System.out.println("Déconnexion du client");
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}}} ES-SALHI| Java Avancé
Exemple d’un client simple
import java.io.*;import java.net.*;import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
System.out.println(" Créer une connexion au serveur:");
Socket clientSocket=new Socket("localhost", 123);
System.out.println("Génération de objet InptStream et OutputStream
de la socket");
InputStream is=clientSocket.getInputStream();
OutputStream os=clientSocket.getOutputStream();
System.out.print("Lire un nombre au clavier NB=");
Scanner clavier=new Scanner(System.in);
int nb=clavier.nextInt();
System.out.println("Envoyer le nombre "+nb+" au serveur");
os.write(nb);
System.out.println("Attendre la réponse du serveur:");
int rep=is.read();
System.out.println("La réponse est :"+rep);
} catch (Exception e) {
e.printStackTrace();
}}}
ES-SALHI| Java Avancé : JDBC
Recevoir et envoyer des chaînes de caractères

 Création de l’objet ServerSocket


 ServerSocket ss=new ServerSocket(2345);
 Attendre une connexion d’un client
 Socket sock=ss.accept();
 Pour lire une chaîne de caractère envoyée par le client :
 InputStream is=sock.getInputStream();
 InputStreamReader isr=new InputStreamReader(is);
 BufferedReader br=new BufferedReader(isr);
 String s=br.readLine();
 Pour envoyer une chaîne de caractères au client
 OutputStream os=sock.getOutputStream();
 PrintWriter pw=new PrintWriter(os,true);
 pw.println("Chaîne de caractères");
ES-SALHI| Java Avancé
R/E des objets (Sérialisation et désérialisation)

 Une classe Sérializable:


 public class Voiture implements Serializable{
 String mat;int carburant;
 public Voiture(String m, int c) { mat=m; carburant=c;}
 }
 Pour sérialiser un objet (envoyer un objet vers le client)
 OutputStream os =sock. getOutputStream();
 ObjectOutputStream oos=new ObjectOutputStream(os);
 Voiture v1=new Voiture("v212",50);
 oos.writeObject(v1);
 Pour lire un objet envoyé par le client ( désérialisation)
 InputStream is =sock. getInputStream();
 ObjectInputStream ois=new ObjectInputStream(is);
 Voiture v=(Voiture) ois.readObject();
ES-SALHI| Java Avancé
Serveur Multi-Threads

 Pour qu’un serveur puisse communiquer avec plusieurs


client en même temps, il faut que:
 Le serveur puisse attendre une connexion à tout
moment.
 Pour chaque connexion, il faut créer un nouveau thread
associé à la socket du client connecté, puis attendre à
nouveau une nouvelle connexion
 Le thread créé doit s’occuper des opérations d’entrées-
sorties (read/write) pour communiquer avec le client
indépendamment des autres activités du serveur.

ES-SALHI| Java Avancé


Connection Multi-Threads
Serveur
Connexion
ServerSocket
Thread

ClientSocket:Socket Socket
is os
Thread Thread1
os is

ClientSocket:Socket
is os
Socket
Thread os is
Thread2
ES-SALHI| Java Avancé
Implémentation d’un serveur multi-thread

 Suite en TP

ES-SALHI| Java Avancé

Vous aimerez peut-être aussi