La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Voisin-Polian : Introduction à Java 1 Introduction à Java - les « Threads » - Frédéric VOISIN – Nicole POLIAN FIIFO - « Remise à Niveau »

Présentations similaires


Présentation au sujet: "Voisin-Polian : Introduction à Java 1 Introduction à Java - les « Threads » - Frédéric VOISIN – Nicole POLIAN FIIFO - « Remise à Niveau »"— Transcription de la présentation:

1

2 Voisin-Polian : Introduction à Java 1 Introduction à Java - les « Threads » - Frédéric VOISIN – Nicole POLIAN FIIFO - « Remise à Niveau »

3 Voisin-Polian : Introduction à Java 2 Les « Threads » Java (ou « processus légers ») n Ils permettent de lancer plusieurs tâches en même temps au sein dun même processus n Ils permettent de refléter des découpages logiques en composants sexécutant indépendamment ou en coopération Ils sont utilisés en interne par Java : le ramasse-miette est un thread de faible priorité, la méthode main(String[] args) sexécute dans un thread … n Les threads partagent la même zone mémoire, ce qui facilite la communication entre threads. Le temps de commutation entre threads est inférieur à celui des processus.

4 Voisin-Polian : Introduction à Java 3 Exemple (presque) sans thread public class Train { int vitesse; String nom; public Train(int v, String n){ vitesse = v; nom = n;} public void run() { System.out.println(nom + " part"); try { Thread.currentThread().sleep(vitesse*500); } catch (InterruptedException e) {} System.out.println(nom + " roule"); try { Thread.currentThread().sleep(vitesse*50); } catch (InterruptedException e) {} System.out.println(nom + " s'arrete"); } La méthode main sexécute dans un thread ! Le déroulement de sleep pourrait être abrégé par une « interruption », doù le try/catch

5 Voisin-Polian : Introduction à Java 4 Exemple sans thread (suite) // lancement de trois trains de vitesses différentes public class TestTrain { public static void main (String[] args) { Train micheline = new Train(50, "MICHELINE"); Train tgv = new Train(10, "TGV"); Train corail = new Train(20, "CORAIL"); micheline.run(); tgv.run (); corail.run(); System.out.println("fin du main"); } MICHELINE part MICHELINE roule MICHELINE s'arrete TGV part TGV roule TGV s'arrete CORAIL part CORAIL roule CORAIL s'arrete fin du main

6 Voisin-Polian : Introduction à Java 5 Exemple avec thread public class Test { public static void main(String[] args) { Train tgv = new Train(10, "TGV"); Train corail = new Train(20,"CORAIL"); Train micheline = new train (50, "MICHELINE"); micheline.start(); tgv.start(); corail.start(); System.out.println("Threads actifs : " + Thread.currentThread().activeCount()); try { corail.join(); // attendre la fin de corail ! } catch (InterruptedException ex) { } System.out.println("Threads actifs : " + Thread.currentThread().activeCount()); System.out.println("fin du main"); }

7 Voisin-Polian : Introduction à Java 6 Exemple avec thread (suite) class Train extends Thread { int vitesse; public Train(int v, String n) { super(n); // permet de « nommer » le thread. // getName() renvoie le nom ! vitesse = v; } public void run() { System.out.println(getName() + " part"); try { sleep(vitesse*500); } catch(InterruptedException e) { } System.out.println(getName() + " roule"); try { sleep(vitesse*50); } catch(InterruptedException e) { } System.out.println(getName() + " s'arrete"); } Exemple dexécution Threads actifs : 4 MICHELINE part TGV part CORAIL part TGV roule TGV s'arrete CORAIL roule CORAIL s'arrete Threads actifs : 2 fin du main MICHELINE roule MICHELINE s'arrete

8 Voisin-Polian : Introduction à Java 7 Le principe des Threads La classe Train dérive de la classe Thread. La méthode start démarre le thread, ce qui entraîne lappel de la méthode run. Le thread termine quand il atteint la fin de la méthode run. La méthode join permet de se synchroniser avec la fin dun thread. n Une autre synchronisation serait nécessaire si le thread produisait des résultats à récupérer (à voir après) Lhéritage multiple nexistant pas en Java, il existe un deuxième mécanisme pour utiliser les threads : lutilisation de linterface Runnable, qui impose lexistence dune méthode run. On passe alors une instance dune classe qui implémente Runnable comme premier argument au constructeur de Thread.

9 Voisin-Polian : Introduction à Java 8 Utilisation de linterface Runnable public class Test { public static void main(String[] args) { Thread tgv = new Thread(new Train(10, "TGV")); Thread corail = new Thread(new Train(20, "CORAIL")); Thread micheline = new Thread(new Train(50, "MICHELINE")); micheline.start(); tgv.start(); corail.start(); System.out.println("fin du main") ; } // le paramètre du constructeur de Thread doit implémenter linterface Runnable !

10 Voisin-Polian : Introduction à Java 9 Utilisation de linterface Runnable (suite) public class Train implements Runnable { int v; String nom; public Train(int i, String n) { v = i; nom = n;} public void run() { System.out.println(nom + " part"); try { Thread.currentThread().sleep(v*500); } catch(InterruptedException e) {} System.out.println(nom + " roule"); try { Thread.currentThread().sleep(v*50); } catch(InterruptedException e) {} System.out.println(nom + " s'arrete"); } fin du main MICHELINE part TGV part CORAIL part TGV roule TGV s'arrete CORAIL roule CORAIL s'arrete MICHELINE roule MICHELINE s'arrete

11 Voisin-Polian : Introduction à Java 10 Les états dun Thread créé actif En attente mort new ( ) terminaison start ( ) wait ( ) ou sleep ( ) notify ( ) ou interruption

12 Voisin-Polian : Introduction à Java 11 Les principales méthodes liées aux threads statiques : currentThread() activeCount() // threads démarrés et pas encore morts enumerate() // permet de les copier dans un tableau // Thread[] th=new Thread[nb];nb=Thread.enumerate(th); yield() // rend la main volontairement pour un autre thread sleep() // ne relâche pas les moniteurs (cf. infra) non statiques isAlive() join() setDaemon() // à faire avant start() ! isDaemon() dans Object // pour les moniteurs (synchronisation de threads) wait // en attente de notification notify // notification « Deprecated » (induisent de forts risques de deadlock, cf. infra) stop, suspend, resume

13 Voisin-Polian : Introduction à Java 12 Exemple de Thread public class Heure1 extends Frame { // utilisation de AWT !! Label l1, l2, h1, h2; Button arret1; Timer1 t1, t2; Heure1() { setLayout(new FlowLayout()); l1 = new Label (" "); l2 = new Label (" "); l1.setBackground(Color.white); l2.setBackground(Color.white); l1.setAlignment(Label.CENTER); l2.setAlignment(Label.CENTER); Font f = new Font("TimesRoman", Font.PLAIN, 18); setFont(f); arret1 = new Button ("STOP"); h1 = new Label("MONTREAL"); h2 = new Label("PARIS"); ActionListener larret1 = new ActionListener() { public void actionPerformed(ActionEvent e){ System.exit(1);} }; // classe interne, définie au vol ! … // ActionListener est une interface associée aux événements click sur les boutons

14 Voisin-Polian : Introduction à Java 13 Exemple de Thread (suite) arret1.addActionListener(larret1); // associe action/bouton add(arret1); // ajout des composants add(l1); add(h1); // à linstance de Frame add(l2); add(h2); t1 = new Timer1(l1, 1); t2 = new Timer1(l2, 2); t1.start(); t2.start(); } // fin de Heure1() public static void main(String[] args) { Heure1 t = new Heure1(); t.setBounds(20, 20, 800, 60); t.setVisible(true); }

15 Voisin-Polian : Introduction à Java 14 Exemple de Thread (suite) public class Timer1 extends Thread { Label l; int type; Date maDate; SimpleDateFormat mF = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); public Timer1(Label l, int t) { this.l = l; type = t; } public void run() { while (true) { try { sleep (2000); } catch(InterruptedException e) {} maDate = new Date(); if (type == 1) { mF.setTimeZone(TimeZone.getTimeZone("America/Montreal")); L.setText(mF.format(maDate)); } else { mF.setTimeZone(TimeZone.getTimeZone("Europe/Paris")); L.setText(mF.format(maDate)); }

16 Voisin-Polian : Introduction à Java 15 Les démons (« daemon ») n Il existe deux sortes de threads u les threads ordinaires (utilisateurs) u les threads démons (notamment créés par la JVM; exemple : le ramasse-miettes) n deux méthodes setDaemon(boolean b) // à exécuter avant start boolean isDaemon() n Un « processus » Java sarrête lorsquil ne reste plus que des threads démons. Ceux-ci correspondent à des threads « de service » qui ne contribuent pas directement à la logique applicative.

17 Voisin-Polian : Introduction à Java 16 Lordonnancement (scheduling) n Question : quel thread a la main ? celui qui a la plus grande priorité parmi les threads actifs ! n pour changer la priorité : getPriority() setPriority() Thread.MIN_PRIORITY Thread.MAX_PRIORITY u Thread.NORM_PRIORITY n En cas dégalité, certaines implémentation laissent la main au thread en cours (pas déquité entre les threads potentiellement activables). Dans ce cas, il faut utiliser la méthode yield() ou bien sleep(0) pour relâcher la main.

18 Voisin-Polian : Introduction à Java 17 Arrêter un Thread public class TestArret { public static void main(String[] args) { tt = new Train(); tt.start(); try { Thread.currentThread().sleep(2000); tt.stoppe(); tt.join(); } catch (InterruptedException ex) {} System.out.println("fin du main"); } class Train extends Thread { private boolean arrete = false; public void run() { while (! arrete) { System.out.println("le train roule"); try { sleep(500);} catch(InterruptedException e) {} } System.out.println("le train s'arrete"); } public void stoppe() { arrete = true ; } } // accès sans précaution à arrete ;-( le train roule le train s'arrete fin du main

19 Voisin-Polian : Introduction à Java 18 Problèmes de synchronisation n Les threads partagent les mêmes données et agissent sur les mêmes objets problèmes daccès incohérents aux données On peut protéger une suite dinstruction (ou une fonction) avec synchronized Pour une fonction : à tout instant il sexécute au plus une fonction synchronized sur un objet donné… mais les fonctions non synchronized nont aucune obligation synchronized int fonct() { … } Par « verrouillage » dun objet (arbitraire) pour une suite dinstructions arbitraire : synchronized (obj) { // au plus une séquence dinstructions ou méthode // synchronized à la fois sur obj. obj.action(); … } Reprend les principes des moniteurs de Hoare/Brinch Hansen

20 Voisin-Polian : Introduction à Java 19 Exemple de synchronisation class Truc { int val = 0; void incr(int tempo) { int i = val; try { Thread.currentThread().sleep(tempo); } catch (InterruptedException e) {} val = i+1; // la valeur de val il y a un certain temps ! try { Thread.currentThread().sleep(tempo) ; } catch (InterruptedException ex) { } ; } public String toString() { return "valeur " + val;}} class Collision { static truc cpt = new truc(); public static void main(String[] arg) { Compteur t1 = new Compteur(cpt,1); Compteur t2 = new Compteur(cpt,2); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException ex) {}; System.out.println("fin du main : " + cpt); }}

21 Voisin-Polian : Introduction à Java 20 Exemple de synchronisation (suite) class Compteur extends Thread { int num; truc cpt; Random rd; public Compteur (truc c, int nm) { num = nm; cpt = c; rd = new Random(nm); } public void run() { System.out.println("debut run " + num); for(int i = 0; i<100; i++) { // synchronized(cpt) { cpt.incr(Math.abs(rd.nextInt())); } System.out.println ("fin run " + num); } sans synchronized(cpt) debut run 1 debut run 2 fin run 1 fin run 2 fin du main : valeur 143 avec synchronized(cpt) debut run 1 debut run 2 fin run 1 fin run 2 fin du main : valeur 200

22 Voisin-Polian : Introduction à Java 21 Les appels wait et notify wait bloque lexécution du thread jusquà réception dune « notification » envoyée par un autre thread. Le verrou sur lobjet est levé (à la différence de sleep !) notify envoie la notification précédente : « réveil » du (ou plutôt dun) thread bloqué. notifyAll () réveille tous les threads bloqués sur cet objet. Attention: les threads débloqués doivent encore « acquérir » lobjet sur lequel ils se synchronisent. Ils sont en concurrence avec tous les autres threads similaires (pas de privilège daccès). Souvent on doit englober le wait dans une boucle daccès en attendant quune certaine condition soit effectivement réalisée. n Attention aux deadlocks, si on acquiert les objets dans le désordre ou si on oublie den libérer laccès !

23 Voisin-Polian : Introduction à Java 22 wait et notify (suite) synchronized ( obj ) { obj.wait ( ) ; } synchronized ( obj ) { obj.notify ( ) ; } T1.. T réveil Lattente se fait « sur » un objet. Le notify est envoyé à ce même objet. Lobjet doit « appartenir » au thread qui exécute wait/notify, cela implique lutilisation obligatoire de synchronized. Gérer le verrou sur un objet nécessite dacquérir cet objet !

24 Voisin-Polian : Introduction à Java 23 Un Exemple public class Heure2 extends Frame { Label l1, l2; Button h1, h2, arret1; Timer2 t1, t2; Heure2() { setLayout(new FlowLayout()); l1 = new Label(" "); l2 = new Label(" "); l1.setBackground(Color.white); l2.setBackground(Color.white); l1.setAlignment(Label.CENTER); l2.setAlignment(Label.CENTER); Font f = new Font("TimesRoman", Font.PLAIN, 18); setFont(f); arret1 = new Button("Stop Montreal"); h1 = new Button("MONTREAL"); h2 = new Button("PARIS"); ActionListener larret1 = new ActionListener() { public void actionPerformed(ActionEvent e) { t1.stoppe(); // arret definitif de l'horloge locale remove(l1); remove(h1); remove(arret); }}; …

25 Voisin-Polian : Introduction à Java 24 Un Exemple (suite) ActionListener lh2 = new ActionListener() { public void actionPerformed(ActionEvent e) { if (! t2.isAlive()) { t2.start(); } }} ; ActionListener lh1 = new ActionListener() { public void actionPerformed(ActionEvent e) { if (! t1.isAlive()) { t1.start(); } else { t1.bascule(); } }}; arret1.addActionListener(larret1); h1.addActionListener(lh1; h2.addActionListener(lh2); add(arret1); add(l1); add(h1); add(l2); add(h2); t1 = new Timer2(l1, 1); t2 = new Timer2(lab2, 2); } public static void main(String[] arg) { Heure2 t = new Heure2(); t.setBounds(20, 20, 800, 60); t.setVisible(true); }

26 Voisin-Polian : Introduction à Java 25 Un Exemple (suite) class Timer2 extends Thread { Label L; int type; boolean marche, actif; public Timer2(Label l, int t) { L = l; type = t; marche = true; actif = true; } public void stoppe() { marche = false; } public void bascule() { if (actif) { actif = false ; } else { synchronized(L) { L.notify(); } } }

27 Voisin-Polian : Introduction à Java 26 Un Exemple (suite) public void run() { Date maDate; SimpleDateFormat mF=new SimpleDateFormat("dd-MMM-yyyyHH:mm:ss"); while (marche) { try { sleep (2000); } catch (InterruptedException ex) {} if (! actif) { try { synchronized(L) { L.wait(); } } catch (InterruptedException ex) {} actif = true ; } maDate = new Date(); if (type == 1){ mF.setTimeZone(TimeZone.getTimeZone("America/Montreal")); L.setText(monFormat.format(maDate)); } else { mF.setTimeZone(TimeZone.getTimeZone("Europe/Paris")); L.setText(mF.format(maDate)); } }}}

28 Voisin-Polian : Introduction à Java 27 Un Exemple (affichage)


Télécharger ppt "Voisin-Polian : Introduction à Java 1 Introduction à Java - les « Threads » - Frédéric VOISIN – Nicole POLIAN FIIFO - « Remise à Niveau »"

Présentations similaires


Annonces Google