Plan
Concurrence vs. Parallélisme
Implémentation du thread
Cycle de vie
Concurrence d’accès
2
Muti-tâches
Multi-tâches : exécution de plusieurs processus
simultanément.
o Un processus est un programme en cours d'exécution.
o Le OS distribue le temps CPU entre les processus
Un processus peut être dans différents états.
o En exécution (running) : il utilise le processeur
o Prêt : le processus est prêt à s'exécuter, mais n'a pas le
processeur (occupé par un autre processus en
exécution)
o Bloqué
3
Parallélisme
Parallélisme : Exécuter plusieurs tâches à un ordinateur
avec plusieurs processeurs.
Si l’ordinateur possède moins de processeurs que de
processus à exécuter :
o Division du temps d’utilisation du processeur en tranches de
temps (Time slice)
o Attribution des tranches de temps à chacune des tâches de
façon telle qu’on ait l’impression que les tâches se déroulent
en parallèle (pseudo-parallélisme)
o Les OS modernes gèrent le Muti-tâches et le Parallélisme
4
Concurrence vs. Parallélisme
CPU CPU1 CPU2
5
Qu'est ce qu'un thread
Les threads sont différents des processus :
o ils partagent code, données et ressources : « processus
légers »
o mais peuvent disposer de leurs propres données.
o ils peuvent s’exécuter en "parallèle"
Avantages :
o légèreté grâce au partage des données
o meilleures performances au lancement et en exécution
o partage les ressources système (pratique pour les I/O)
Utilité :
o puissance de la modélisation : un monde multithread
o puissance d’exécution : paralèllisme
o simplicité d’utilisation : c’est un objet Java ([Link]) 6
Threads vs. Processus
CPU
main
run
Process 1 Process 2 Process 3 Process 4
GC
7
Pour créer des Threads…
Deux méthodes, un point commun :
« écrire une méthode run() qui fait ce que doit
faire le thread. »
o Méthode 1 : Dériver une classe de Thread.
o Méthode 2 : implémenter l’interface Runnable.
L’interface Runnable
interface Runnable
{
public abstract void run() ;
}
Un objet « runnable » est un objet que l’on
peut lancer en faisant run()…
La classe Thread
public class Thread implements Runnable {
public static final int MAX_PRIORITY, MIN _PRIORITY, NORM _PRIORITY;
public Thread();
public Thread(String name);
…
public static Thread currentThread();
public static void sleep(long millis); // arrête le thread pour un millis seconde
public static void wait(); //arrête le thread en attendant une notification
public static void notify(); // notification des threads en attentes par wait
public static void suspend();
public static void resume();
…
public static void start();
public static void stop();
public static void run();
…
}
Dériver une classe de Thread
public class SimpleThread extends Thread {
public void run() {
//code exécuté dans un processus propre
} Partie Utile
SimpleThread unSimpleThread = new SimpleThread();
[Link]();
Implémenter l’interface Runnable
public class Clock implements Runnable {
public void run() {
while(true){ …}
}
Partie Utile
Clock uneClock = new Clock();
Thread thread = new Thread(uneClock);
[Link]();
… Cible Runnable
Quelle technique choisir ?
Avantages Inconvénients
Chaque thread a ses On ne peut plus
extends Thread données qui lui sont hériter d'une autre
propres. classe.
L'héritage reste Les attributs de votre
possible. En effet, on classe sont partagés
implements peut implémenter pour tous les threads
Runnable autant d'interfaces que qui y sont basés. Dans
l'on souhaite. certains cas, il peut
s'avérer que cela soit
un atout.
Gestion des threads
Cycle de vie d'un thread
Démarrage, suspension, reprise et
arrêt d'un thread.
public void start() : Permet de démarrer un thread.
public void suspend() : Arrête temporairement un thread en
cours d'exécution.
public void resume() : Relance l'exécution d'un thread, mis
en pause via suspend. Attention, le thread ne reprend pas au
début du run, mais continue son job
public void stop() : Stoppe de manière définitive, l'exécution
du thread. Aussi lors de la sortie de la méthode run.
Ordonnancement des threads
Chaque thread possède une priorité : Trois constantes
de la classe Thread pour définir les priorités :
o MAX_PRIORITY : niveau de priorité maximal possible (10)
o MIN_PRIORITY : niveau de priorité minimal possible (1)
o NORM_PRIORITY : niveau de priorité par défaut (5)
main thread est créé avec une priorité
NORM_PRIORITY
Concurrence d’accès
int k = 0;
Thread #1: Thread #2:
k = k + 1; [Link](k);
• Quelle sera la valeur affiché par k?
• Exemple trivial à un problème difficile
17
Concurrence d’accès
• Problème : espace de travail commun, pas de
"mémoire privée" pour chaque thread :
– inconvénient : accès simultané à une même
ressource.
– Il faut garantir l’accès exclusif à un objet pendant
l’exécution d’une ou plusieurs instructions
• Pour se faire : le mot-clé synchronized permet de
gérer les concurrence d’accès :
– d’une méthode
– d’un objet
– ou d’une instruction (ou18 d’un bloc)
Les vérrous et les objets
Tout objet possède un vérrou, et ce vérrou n'a qu'une clé.
Lorsqu'un thread veut entrer dans une méthodesynchronisée, il
doit obtenir la clé de l'objet. Si la clé est disponible, i.e. aucun
autre thread ne la détient, le thread prend la clé et entre dans la
méthode. Dès lors le thread gardera la clé tant qu'il n'aura pas
terminé la méthode synchronisée.
Si la clé de l'objet n'est pas disponible, aucun thread ne peut
entrer dans une méthode synchronisée de cet objet.
19
Concurrence d’accès
public class MyThread implements Runnable{
String number;
public MyThread(String number){
[Link]=number;
}
public void run(){
synchronized(this){
int i;
for(i=0;i<50;i++)
[Link](number+i);
}
}
public static void main(String[] args){
MyThread pa=new MyThread("Processus 1 :");
Thread th=new Thread(pa);
MyThread pa2=new MyThread("Processus 2 :");
Thread th2=new Thread(pa2);
[Link]();
[Link](); 20
} }
Exemple
Concurrence d’accès
21
Consumer
• Consumer:
synchronized (lock) {
while (!resourceAvailable()) {
[Link]();
}
consumeResource();
}
22
Producer
• Producer:
produceResource();
synchronized (lock) {
[Link]();
}
23
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
[Link] from wait()
Consumer Producer
Thread Thread
24
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
25
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
26
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
27
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
28
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
29
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
30
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
31
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
32
Wait/Notify Sequence
Lock Object
1. synchronized(lock){ 3. produceResource()
2. [Link](); 4. synchronized(lock)
5. [Link]();
9. consumeResource();
10. } 6.}
7. Reacquire lock
8. Return from wait()
Consumer Producer
Thread Thread
33
Fin
34