Le multitâche en Java

Transcription

Le multitâche en Java
Le multitâche en Java
Premier Cycle
Cours EURINSA 2002
(c) P.Pollet
05/12/2002
Java 2001 (PP)
1
Plan
◆ Définition des threads
◆ Créer un thread
◆ Le problème de la synchronisation
◆ Les signaux
◆ Exemple I: Producteurs et Consommateurs
◆ Exemple II: Animation d ’applettes
05/12/2002
Java 2001 (PP)
2
Définition des threads
◆ La machine virtuelle JVM permet l ’exécution concurrente de
plusieurs processus dans un même programme.
◆ Un processus est un objet sous-classe de java.lang.Thread qui
possède:
–
–
–
–
une instruction courante
un environnement (ses variables d ’instance)
un état (créé, actif, endormi,en attente, inactif, mort…)
un nom
◆ Les Thread communiquent entre eux par des signaux (wait(),
notify()).
◆ Les Thread doivent rendre la main à la JVM par leurs méthodes
sleep(), yield() ou suspend() (multitâche coopératif).
◆ Les threads peuvent avoir des priorités différentes.
05/12/2002
Java 2001 (PP)
3
Créer un thread
◆ Deux façons de créer un Thread:
◆ Sous-classer java.lang.Thread en redéfinissant au moins la
méthode run().
Class MonThread extends Thread {
public void run() {
……. }
}
Méthode la plus simple.
◆ Implémenter l ’interface java.lang.Runnable et implémenter run()
Class MaClasse extends SonAncetre implements Runnable {
Thread monThread; // à créer et à lancer dans un constructeur ou init()
public void run() {
…….
Méthode obligatoire si une super-classe
}
est requise (applette).
}
05/12/2002
Java 2001 (PP)
4
Etendre Thread
◆ L ’appel à start() enregistre le Thread auprès de la JVM et
appelle la méthode run() redéfinie qui réalise le travail.
◆ Le Thread meurt automatiquement si la méthode run() se
termine.
class Producteur extends Thread {
Producteur (….) { // un éventuel constructeur
super(); ….
Forme standard:
}
Ne pas oublier d ’appeler
public void run () {
sleep(), wait(), suspend(), yield()...
while (true) {…………}
}
}
Producteur p1=new Producteur (….); p1.start();
Producteur p2=new Producteur(…..); p2.start();
05/12/2002
Java 2001 (PP)
5
Implémenter Runnable
◆ Obligatoire sur la classe a une superclasse (pas d ’héritage
multiple en Java)
class Producteur extends SuperClasse implements Runnable {
public Thread monThread;
Producteur (….) { // un constructeur obligatoire pour créer le processus
super(...); ….
monThread=new Thread(this);
Notez le this pour associer
}
le Thread à cette classe.
public void run () {
Même code que dans le cas
while (true) {…………}
précédent (sleep(),....
}
}
Producteur p1=new Producteur (….); p1.monThread.start();
Producteur p2=new Producteur(…..); p2.monThread.start();
05/12/2002
Java 2001 (PP)
6
Le problème de la synchronisation
◆ Tous les processus accèdent aux ressources publiques du
programme (instances d ’objets, variables, fichiers…).
◆ Il faut mettre en place un accès exclusif pendant l ’exécution
d un bloc d’instructions.
◆ Exemple:
–un processus dessine des points (en 4 instructions) alors qu’un second les déplace
(en 2 instructions). Il faut garantir que ces instructions ne seront pas interrompues !
◆ Mot clé synchronized:
–Permet de gérer les accès concurrents sur
–une méthode :
–une classe :
–un bloc:
public synchronized maMethode() {……}
synchronized (monObjet) { monObjet.saMethode();}
synchronized (unTruc) { // manipule unTruc....}
–on définit ainsi une section critique avec mise en attente
automatique par la JVM des autres processus.
05/12/2002
Java 2001 (PP)
7
Les signaux
◆ Toutes les classes Java héritent de Object et disposent donc d ’un
moniteur d ’accès à travers wait() et notify().
◆ Lorsqu’un processus accède à un objet il peut appeler la méthode
wait() de cet objet. (monObjet.wait())
• Relâche l ’accès à l ’objet et s ’endort.
• attend une notification des autres processus.
• redémarre dès qu’il obtient à nouveau l’accès exclusif
◆ Lorsqu ’un processus a «fini » avec un objet, il appelle sa méthode
notify (). (monObjet.notify()).
• Signale aux processus qui ont fait un wait, qu’ils peuvent se réveiller.
• Ne relâche pas l ’accès (=>à faire en fin de bloc synchronisé).
• Ne peut se faire que si on a eu l ’accès (dans un bloc synchronisé)
◆ Permet une synchronisation de type Producteur-Consommateur.
05/12/2002
Java 2001 (PP)
8
Exemple I:
un producteur de nombres
◆ Dépose dans un tableau de taille limitée des nombres qui sont pris
par des consommateurs.
class Producteur extends Thread {
Une pause d ’une seconde
public void run () {
while (true){
try {sleep (1000);} catch (InterruptedException e) {};
synchronized (table) {
Section critique
if (table.estPleine()) try {table.wait();} catch (InterruptedException e) {};
table.ajoute((int)( Math.random()*1000));
table.notify();
Attente si table est pleine
}
}
}
Signale aux consommateurs et aux
autres producteurs (!) de se réveiller...
05/12/2002
Java 2001 (PP)
9
Exemple I:
un consommateur de nombres
◆ Prends dans un tableau de taille limitée des nombres qui y sont
placés par des producteurs.
class Consommateur extends Thread {
Une pause d ’une seconde
public void run () {
while (true){
try {sleep (1000);} catch (InterruptedException e) {};
synchronized (table) {
Section critique
if (table.estVide()) try {table.wait();} catch (InterruptedException e) {};
System.out.println (table.retire());
table.notify();
Attente si table est vide
}
}
}
Signale aux producteurs et aux
autres consommateurs (!) de se réveiller...
05/12/2002
Java 2001 (PP)
10
Exemple II:
Animation dans une applette.
◆ Un Thread dessinateur dessine des rectangles qui se déplacent dans leur
propre processus:
public class Animateur extends java.applet.Applet implements Runnable {
RectangleMobile r1,r2,r3; Thread dessinateur;
Une petite pause
public void run () {
entre chaque affichage
while (true){
try {dessinateur.sleep (10);} catch (InterruptedException e) {}
repaint();
Création de quatre processus:
}}
un pour le dessinateur et un
public void paint(Graphics g) {
pour chaque rectangle
r1.paint(g); r2.paint(g);r3.paint(g);}
public void start() {
r1=new RectangleMobile (Color.red,50,50,5,5,100); r1.start();
r2=new RectangleMobile (Color.black,100,0,15,15,300); r2.start();
r3=new RectangleMobile (Color.blue, 0,100,25,25,200); r3.start();
dessinateur=new Thread(this); dessinateur.start();
}}
05/12/2002
Java 2001 (PP)
11
Exemple II:
les rectangles mobiles.
public class RectangleMobile extends Thread {
Color c; int rx,ry,dx,dy,dt;
RectangleMobile (Color c, int rx, int ry, int dx, int dy, int dt ) {
this.c=c;this.rx=rx;this.ry=ry; this.dx=dx; this.dy=dy;this.dt=dt;
}
Une pause de dt
public void run () {
entre chaque mouvement
while (true){
try {sleep (dt);} catch (InterruptedException e) {}
Ne sort pas de l ’écran !
if ((rx+dx <0) || (rx+dx)>200) dx= -dx;
if ((ry+dy <0) || (ry+dy)>200) dy= -dy;
rx +=dx; ry +=dy;}
}
Section critique !
public synchronized void paint(Graphics g) {
g.setColor( c);g.fillRect (rx,ry,30,30);
}
05/12/2002}
Java 2001 (PP)
12