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

Programmation Objet en JAVA Cours 8 Thread, Multi-thread, synchronisation,...

Présentations similaires


Présentation au sujet: "Programmation Objet en JAVA Cours 8 Thread, Multi-thread, synchronisation,..."— Transcription de la présentation:

1 Programmation Objet en JAVA Cours 8 Thread, Multi-thread, synchronisation,...

2 Faisons une interface réactive. Réaliser l'éditeur simple permettant : –visualiser l'heure (en temps réel ! ) –insérer la date et l'heure automatiquement –éditer le texte et, –sauver le texte. Une fenêtre –3 boutons 1 action par bouton –Zone d'affichage zone de texte « éditable » sur plusieurs lignes

3 Hiérarchie « graphique » simple

4 Hiérarchie « graphique » plus générique

5 Implémentation de l'éditeur simple - V1 L'application hérite d'une JFrame. Le constructeur prend en charge l'initialisation propre de l'interface. La « montre » dans sa version graphique nécessite l'implémentation d'une classe MontreG : héritage d'un JLabel + méthode de mise à jour de l'heure. En attributs, les composants nécessaires : –3 x JButton + 1 x JTextArea + 1 x MontreG. Implémenter les « ActionListener » correspondant aux boutons tels qu'ils puissent accéder à l'heure et l'insérer dans la zone de texte : –sous forme de classes internes, ou –l'application implements MouseListener, ou –Créer une classe regroupant les actions (prévoir les accès et modifications public des attributs ).

6 La classe MontreG import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MontreG extends JLabel{ public MontreG(){ super("Press start to get time"); }; public void go(){ while (true) { try { Thread.sleep(1000); } catch(InterruptedException e) { System.err.println("Interrupted"); } this.setText(new java.util.Date().toString()); } public static void main(String[] args) {...} }

7 La classe de l'application (résumé) import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EdMontreBof extends JFrame { /* Les attributs sont les composants graphiques */ private MontreG montre; private JTextArea editor; private JButton startB; private JButton printB; private JButton saveB; /* Définition des ActionListener en classes internes */ class StartL implements ActionListener {... } class PrintL implements ActionListener {... } class SaveL implements ActionListener {... } /* Le constructeur qui initialise tout */ public EdMontreBof(){...} public static void main(String[] args) { EdMontreBof edm = new EdMontreBof(); }

8 La classe de l'application : le constructeur public EdMontreBof(){ super("Pourquoi ?"); this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ) ; this.setSize (250,200) ; /* Construction des composants*/ montre = new MontreG(); startB = new JButton("Start date");// mettre en route la montre printB = new JButton("Print date");// Recopier l'heure dans l'éditeur saveB = new JButton("Save"); startB.addActionListener(new StartL()); printB.addActionListener(new PrintL()); //... pareil pour saveB editor = new JTextArea(5,20); JScrollPane scrollPane = new JScrollPane(editor, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); /* Ajout des composants au container */ Container cp = this.getContentPane(); cp.setLayout(new FlowLayout()); cp.add(montre); cp.add(startB); cp.add(printB);... // pareil pour saveB cp.add(scrollPane); this.setVisible(true); }

9 le constructeur pour l'interface plus complexe public BigEd(){ /* Construction des «feuilles» : pareil */... /* Construction des panels */ left = new JPanel(); right = new JPanel(); /* Construction des composants : pareil */ /* Gestion des events : pareil */ /* Panel de gauche */ left.setLayout(new BoxLayout(left, BoxLayout.PAGE_AXIS)); left.add(montre); left.add(startB); left.add(printB); left.add(saveB); left.setBackground(Color.RED); /* Pour la droite */ right.add(scrollPane); /* Ajout des composants */ Container cp = this.getContentPane(); cp.setLayout(new BorderLayout()); cp.add(left,BorderLayout.WEST); cp.add(right,BorderLayout.EAST); this.setVisible(true); }

10 Retour à l'application simple : les ActionListeners public class EdMontreBof extends JFrame {.... le reste de la classe.... /* Les classes internes ainsi définis ont accès aux attributs et méthodes de la classe EdMontreBof (même privés !).*/ class StartL implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Start"); go(); } class PrintL implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Print"); editor.append("\n"+montre.getText()+ " : "); }.... le reste de la classe.... }

11 Les ActionListeners en classes anonymes dans le constructeur public EdMontreBof(){... printB = new JButton("Print date"); ActionListener pl = new ActionListener(){ public void actionPerformed(ActionEvent e) { System.out.println("Print"); editor.append("\n"+montre.getText()+ " : "); } }; printB.addActionListener(pl); // lequivalent en plus laid : startB = new JButton("Start date"); startB.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { System.out.println("Start"); go(); } }); }

12 Que se passe-t-il ? Tout va bien, jusqu'au moment où la montre est lancée. Tout est bloqué, il est même impossible de fermer la fenêtre.

13 Pour aujourdhui 1.Collection (suite et fin) 2.Retour sur la serialisation 3.Classes internes et interfaces graphiques 4.Thread 5.Projet

14 La solution : les threads Faire en sorte que la montre « tourne » indépendamment de l'application : faire du multi-tâche. Pour résumer : –Un ordinateur est une machine à exécuter pas à pas un programme. –Un programme est une suite dinstructions, son exécution donne lieux à un processus –A un moment donné lordinateur exécute une et une seule instruction –Lorsquil y a plusieurs processus : lordenanceur répartit le temps de CPU pour chacun. –un processus, c'est un PID, un espace mémoire indépendant, un espace d'adressage, un compteur ordinal,.... Gérer par l'OS. En java, il existe des processus « légers » créer par la JVM : les Threads. Un thread est un « fil » d'exécution, un « sous-processus » Un programme java multi-thread : –au sein du même processus (java) –plusieurs fils dexécution sexécutent « en parallèle ». –Lordenanceur répartit le temps de CPU entre les processus et les threads.

15 Ordenancement : 2 processus

16 Ordenancement : processus et thread

17 Les threads en Java Il existe toujours un premier thread qui commence à exécuter la fonction main() Dans les interfaces graphiques –Il existe un autre thread qui attend les actions de lutilisateur et déclenche les écouteurs –Il existe un autre thread qui redessine les composants graphiques qui ont besoin de lêtre On peut créer ses propres threads

18 La classe Thread et l'interface runnable La création d'un thread passe par la création d'un objet de la classe java.lang.Thread. Un objet de type Thread représente la télécommande dun thread réel Il sert à le manipuler (contrôle, priorité, synchronisation) Il faut indiquer au thread quelle méthode exécuter (mais pointeur sur méthode ?) : faire un run de quoi ? Créons un objet qui soit « runnable », il servira de cible au thread. Un objet runnable est un objet qui implémente l'interface Runnable. public interface Runnable { public void run(); } La méthode run est la liste des tâches dun thread, son « main ». Tout thread débute dans la vie par l'exécution d'une méthode run().

19 Création et démarrage - 1 Une fois créer, un thread ne fait rien tant qu'il n'a pas commencer : start(). start() lance l' exécution de run(). Une fois lancer, un thread va jusqu'au bout de run(), du moins tant qu'on ne le stop pas : stop(). class Animation implements Runnable {... public void run() { while ( true ) { // Draw Frames... repaint(); } Animation happy = new Animation("Mr. Happy"); Thread myThread = new Thread( happy ); // Jusqu'ici rien n'est lancé ! myThread.start(); Une première manière, pas très objet.

20 Création et démarrage - 2 Il est préférable, qu'un objet contrôle son propre thread. L'objet est alors autonome. C'est la bonne solution, la plus fréquemment utilisée. class Animation implements Runnable { Thread myThread; // par exemple dans le contructeur Animation (String name) { myThread = new Thread(this); myThread.start(); }... public void run() {...} } Thread myThread start() Création Execution

21 Création et démarrage - 3 On peut rencontrer cependant la solution suivante : hériter de la classe Thread qui implémente Runnable. redéfinir la méthode run(). class Animation extends Thread{ //... start(); public void run() {...} } class Thread implements Runnable..... } Animation fun = new Animation("fun"); fun.start(); // ou bien class Animation extends Thread{ //... Animation (String name) { start(); }

22 Thread : illustration

23 Une vision dun thread public class Thread {... private Runnable target;... public Thread(){... target = this; } public void start(){ target.run(); }

24 Reprenons : utilisation de la classe Thread « The Thread class implements a standard thread that, by default, does nothing. » Il faut redéfinir la méthode public void run() qui décrit la tâche de l'objet de type Thread. Un thread démarre avec l'appel de la méthode start() qui lance run(). Pour réutiliser, une première possibilité est d'hériter de Thread. –Mais notre application (ou notre montre) hérite déjà ! La seconde possibilité implémenter l'interface Runnable et construire un thread qui pour cible un objet Runnable. –Il existe l'interface Runnable qui impose la méthode run(). –Un objet Runnable contient ce que le thread doit exécuter.

25 Hériter de Thread ou non. Hériter de Thread semble simple, mais... Il est important de concevoir vos classes selon une structure objet cohérente : –la méthode run() est souvent relative à la fonctionnalité d'une classe particulière (par exemple la montre, l'animation,...). –run() devrait être implémentée dans cette classe,... plutôt que dans une classe représentant un thread. Implémenter l'interface Runnable permet : –de faire un design objet cohérent. –d'hériter d'une autre classe que Thread (JFrame, JLabel,...); –permettre à run() d'accéder aux membres privés de la classe.

26 Contrôle des threads La vie d'une thread démarre par l'appel de start() qui lance run(). stop() détruit le thread en cours. start() et stop() ne peuvent être appelé qu'une fois ! Au contraire de suspend() et resume(). Pour la plupart des utilisations start() et stop() suffisent, c'est lorsque que l'initialisation du thread est importante, qu'il faut utiliser suspend() et resume() : connexion réseau, ressource chargée importante,.... Le sommeil : try { Thread.sleep(1000); } catch (InterruptedException e) { }

27 Implémentation de l'éditeur simple - V2 L'application implémente l'interface Runnable. Rédéfinition de la méthode run(). Ajout d'un attribut de type Thread ciblé sur this. Modification de l'ActionListener StartL. ça marche, mais l'application implémente Runnable : incohérent, C'est la montre qui doit être autonome. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EdMontre2 extends JFrame implements Runnable { /* aux attributs, ajout d'un thread */... private Thread selfThread = null; /* Rédéfinition de run. public void run(){ montre.go(); } /* Modification de StartL */ class StartL implements ActionListener { public void actionPerformed(ActionEvent e) { if(selfThread == null) { selfThread= new Thread(EdMontre2.this); selfThread.start(); } /* Le reste est inchangé : le main, le contructueur,... */

28 Modification de la classe MontreG On crée une nouvelle classe qui hérite de JLabel et qui est Runnable. Redéfinition de la méthode run(). Le constructeur est inchangé. La méthode go() devient inappropriée, elle est supprimée. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MontreGR extends JLabel implements Runnable{ /* Le constructeur est le même, par contre la méthode go() est supprimée. */ public void run(){ while (true) { try { Thread.sleep(100); } catch(InterruptedException e) { System.err.println("Interrupted"); } this.setText(new java.util.Date(). toString()); }

29 Implémentation de l'éditeur simple - V3 L'attribut montre est de type MontreGR. L'attribut de type Thread est conservé. Il aura pour cible l'attribut montre. L'application n'implémente plus l'interface Runnable. Plus de méthode run() dans lapplication. Rédéfinition de la méthode run() dans la montre. Modification de l'ActionListener StartL. Peut mieux faire.... import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EdMontre3 extends JFrame { /* aux attributs, ajout d'un thread */... private Thread clockThread = null; /* Modification de StartL */ class StartL implements ActionListener { public void actionPerformed(ActionEvent e) { if(clockThread == null) { clockThread = new Thread(montre); clockThread.start(); } /* Le reste est inchangé : le main, le contructueur,... */

30 un thread daemon Propose un service général en tâche de fond. Un programme Java s'arrète une fois que tous les threads sont terminés. –tous sauf les daemon. Transformer un thread en daemon : –setDaemon(true); –isDaemon(); Pour la montre, mieux qu'un thread, un daemon.

31 Hériter de Thread public class SimpleThread extends Thread { private int countDown = 5; private static int threadCount = 0; private int threadNumber = ++threadCount; public SimpleThread() { System.out.println("Making " + threadNumber); } public void run() { // la méthode à redéfinir : la tâche du thread. while(true) { System.out.println("Thread " + threadNumber + "(" + countDown + ")"); if(--countDown == 0) return; } public static void main(String[] args) { for(int i = 0; i < 5; i++) new SimpleThread().start();// l'appel de start lance le thread (run) System.out.println("All Threads Started"); } du livre de Bruce Eckel

32 execution de simpleThread Making 1 Making 2 Making 3 Making 4 Making 5 Thread 1(5) Thread 1(4) Thread 1(3) Thread 1(2) Thread 2(5) Thread 2(4) Thread 2(3) Thread 2(2) Thread 2(1) Thread 1(1) All Threads Started Thread 3(5) Thread 4(5) Thread 4(4) Thread 4(3) Thread 4(2) Thread 4(1) Thread 5(5) Thread 5(4) Thread 5(3) Thread 5(2) Thread 5(1) Thread 3(4) Thread 3(3) Thread 3(2) Thread 3(1)

33 Exemple de partage de ressources public class PrimeThread extends Thread int valeur = 0; // valeur est une variable dinstance public void run() { while (true) { System.out.println("thread 18 fait son boulot : "); doJob(18); } public void doJob(int newValeur) { int oldValeur = valeur; valeur = newValeur; System.out.println(" valeur = "+valeur); if (valeur != newValeur) { System.out.println(" ZUT Val="+valeur+" et arg="+newValeur); } valeur = oldValeur; } Attention aux deux appels de fonctions doJob() est appelé par run() et…

34 Lancement public class TestThread { public static void main(String[] ags) { PrimeThread thread1 = new PrimeThread (); thread1.start(); while (true) { System.out.println("L'annee utilisee est : "); thread1.doJob(1789); } Attention aux deux appels de fonctions doJob() est aussi appelé par main()

35 Résultat thread 18 fait son boulot : Valeur = 18 thread 18 fait son boulot : Valeur = 18 thread 18 fait son boulot : Valeur = 18 Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 ZUT Val=1789 et Arg=18 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789 L'annee utilisee est : Valeur = 1789

36 Exemple : Feuille de calcul, tableau dynamique public class SpreadSheet { int cellA1, cellA2, cellA3; public int sumRow() { return cellA1 + cellA2 + cellA3; } public void setRow( int a1, int a2, int a3 ) { cellA1 = a1; cellA2 = a2; cellA3 = a3; }... } Que se passe-t-il si deux threads manipulent un même objet de type SpreadSheet et appellent au même moment sumRow()et setRow() ?

37 Synchronisation Prévenir les collisions au niveau de l'objet et de sa mémoire. Déclarer une méthode synchonized : –un seul thread à la fois peut appeler une méthode synchronized pour un objet donné. Principe d'encapsulation + synchronized : –l'accès aux membres privés se fait via des méthodes synchronized.

38 Verrou (lock) Chaque objet possède un « «monitor » en tant qu'Object. Pour garantir quun bout de code nest exécuté par un seul thread à la fois : synchronized(unObjet){... un seul à la fois...} Lors de l'appel d'une méthode synchronized : –l'objet est-il accessible (non-vérouillé) ? si oui, la méthode est exécutée et l'objet verrouillé; si non, la méthode doit attendre la levée du verrou (que la méthode qui « a le verrou » ai terminé). Pour un objet, 1 seul verrou est partagé par toutes les méthodes synchronized.

39 Exemple : spreadSheet (suite) public class SpreadSheet { int cellA1, cellA2, cellA3; public synchronized int sumRow() { return cellA1 + cellA2 + cellA3; } public synchronized void setRow( int a1, int a2, int a3 ) { cellA1 = a1; cellA2 = a2; cellA3 = a3; }... } Que se passe-t-il si une seule des méthodes est déclarée synchronized ?

40 Critical section Pour partiellement synchroniser une partie d'une méthode : du code « critique » public void run() { while (true) { synchronized(this) { t1.setText(Integer.toString(count1++)); t2.setText(Integer.toString(count2++)); } try { sleep(500); } catch(InterruptedException e) { System.err.println("Interrupted"); }

41 Synchronisation généralisée Synchroniser ce que l'on veut, sur ce que l'on veut. synchronized(syncObject){ /* Ce code ne peut être exécuter que par un seul thread à la fois */... } synchronized void myMethod () {... } void myMethod () { synchronized (this) {... } Ainsi les 2 morceaux de codes suivants sont équivalents.

42 wait() et notify() Dans une méthode synchronized –Le verrou est bloqué à lentrée –puis débloqué à la sortie –Si au milieu de la méthode un thread se rend compte quil ne peux pas remplir ses objectifs car un autre Thread bloqué doit avancer avant ? – INTERBLOQUAGE = cauchemar. –Mieux vaut passer la main si on ne peut plus avancer. Exemple classique du producteur/consommateur –Le producteur fonctionne en flux tendu avec un stock très limité. –Le consommateur consomme le produit à son rythme (il est parfois un peu lent). –Le producteur doit attendre le consommateur pour produire.

43 Producteur / Consommateur Le producteur : –contient un Vector de message –le thread Producteur ajoute un message au vecteur par seconde –Mais le vecteur a une taille maximale –Dans ce cas la méthode putMessage « tourne en rond». Le consommateur : –consomme un message toutes les 2 secondes avec la méthode getMessage du producteur. Synchronisation : les deux méthodes getMessage et putMessage accède au même vecteur ! Il faut donc les synchroniser.

44 Le producteur import java.util.Vector; public class Producer extends Thread { static final int MAXQUEUE = 5; private Vector messages = new Vector(); public void run() { try { while ( true ) { putMessage(); sleep( 1000 ); } catch( InterruptedException e ) { } } private synchronized void putMessage() throws InterruptedException { while (messages.size() == MAXQUEUE){ System.out.println("Waiting); } messages.addElement(new java.util.Date().toString()); } // Called by Consumer public synchronized String getMessage() throws InterruptedException { while ( messages.size() == 0 ) try { sleep( 1000 ); } catch(InterruptedException e){} String message = (String) messages.firstElement(); messages.removeElement(message); return message; }

45 Le consommateur import java.util.Vector; public class Consumer extends Thread { Producer producer; // quel est son producteur. Consumer(Producer p) { producer = p; } public void run() { try { while ( true ) { String message = producer.getMessage(); System.out.println("Got message: " + message); sleep( 2000 ); // il est un peu lent. } catch( InterruptedException e ) { } } public static void main(String args[]) { Producer producer = new Producer(); producer.start(); new Consumer( producer ).start(); }

46 Interblocage

47 Le producteur - 2 import java.util.Vector; public class Producer extends Thread { static final int MAXQUEUE = 5; private Vector messages = new Vector(); public void run() { try { while ( true ) { putMessage(); sleep( 1000 ); } catch( InterruptedException e ) { } } private synchronized void putMessage() throws InterruptedException { while (messages.size() == MAXQUEUE){ wait(); // Attendons System.out.println("Waiting); } messages.addElement(new java.util.Date().toString()); notify(); // Reprenons } // Called by Consumer public synchronized String getMessage() throws InterruptedException { while ( messages.size() == 0 ) wait(); // Attendons String message = (String) messages.firstElement(); messages.removeElement(message); notify(); // Reprenons return message; }

48 Le résultat avec wait et notify Got message: Tue Nov 08 23:46:48 CET 2005 Got message: Tue Nov 08 23:46:49 CET 2005 Got message: Tue Nov 08 23:46:50 CET 2005 Got message: Tue Nov 08 23:46:51 CET 2005 Waiting Got message: Tue Nov 08 23:46:52 CET 2005 Waiting Got message: Tue Nov 08 23:46:53 CET 2005 Waiting....

49 wait en détail (I. Charon) wait est héritée de la classe Object. Cette instruction sutilise dans un code synchronisé. Le thread en cours d'exécution attend. La méthode doit être invoquée sur l'instance verrouillée. Typiquement, on pourra écrire : synchronized(UnObjet) {... while (condition) unObjet.wait();... } Le thread en cours d'exécution est bloqué par unObjet. L'instruction unObjet.wait() signifie que unObjet bloque le thread en cours d'exécution. Ce n'est pas unObjet qui attend. Pendant que la thread attend, le verrou sur unObjet est relâché.

50 notify en détail (I. Charon) Pour pouvoir débloquer un thread qui attend, bloqué par unObjet : synchronized(refereMemeObjetQuUnObjet) {... refereMemeObjetQuUnObjet.notify();... } Si plusieurs threads sont dans lattente imposée par unObjet, l'instruction notify() débloque celle qui attend depuis le plus longtemps. Sinon notifyAll(). Signalons qu'il existe aussi wait(long temps) qui termine l'attente après temps millisecondes, si cela n'est pas fait auparavant.

51 Exemple du pont Supposons un pont entre la France et lAngleterre. Le pont peut être utilisé par un nombre maximum de nmax voitures. Comment gérer le trafic ? Sachant quune voiture ne fait que : –demander lautorisation de passer –quand le feu est vert, elle passe. Le pont est une ressource partagée par les voitures : –une méthode autorisation() –une méthode traversee() –Toutes les voitures ne peuvent pas accéder au pont en même temps. Regardons le main, la voiture.

52 Planification des threads Lorsqu'un thread est lancé, il garde la main jusqu'à ce qu'il atteigne un des états suivants : –Sleeps : appel de Thread.sleep() ou wait(). –Waits for lock : une méthode synchronized est appellée, mais le thread n'a pas le verrou. –Blocks on I/O : lecture de fichier, attente reseau. –Explicit yield control : appel de yield(). –Terminates : la méthode run() du thread est terminé ou appel de stop(). Qui prend la main ensuite ?

53 Gestion des priorités Java propose quelques garanties sur comment les threads sont planifiées (scheduled). Chaque thread possède une priorité. –Si 2 Threads se battent pour obtenir la main … –Si un Thread de plus haute priorité veut la main il lobtient –Si 2 Threads de même priorité se battent : Time slicing Un thread hérite de la priorité de son créateur. La priorité peut être modifiée : int myPriority = Thread.MIN_PRIORITY; thread1.setPriority(myPriority+1); La classe Thread posède les constantes Thread.MIN_PRIORITY (resp. MAX et NORM).

54 Plannification et yield Un thread peut donner de son temps volontairement par l'appel de yield(). Pour faire alterner des threads, c'est la bonne solution. La méthode sleep() doit servir que lorsque l'on souhaite imposer un temps donner de sommeil. S'il s'agit de passer la main : yield().

55 Reprenons l'exemple de Bruce public class SimpleThread extends Thread { private int countDown = 5; private static int threadCount = 0; private int threadNumber = ++threadCount; public SimpleThread() { System.out.println("Making " + threadNumber); } public void run() { // la méthode à redéfinir : la tâche du thread. while(true) { System.out.println("Thread " + threadNumber + "(" + countDown + ")"); if(--countDown == 0) return; } public static void main(String[] args) { for(int i = 0; i < 5; i++) new SimpleThread().start();// l'appel de start lance le thread (run) System.out.println("All Threads Started"); } du livre de Bruce Eckel

56 le résultat sur une autre machine (autre OS). Making 1 Making 2 Making 3 Making 4 Thread 1(5) Thread 1(4) Thread 1(3) Thread 1(2) Thread 1(1) Thread 2(5) Thread 2(4) Thread 2(3) Thread 2(2) Thread 2(1) Thread 3(5) Thread 3(4) Thread 3(3) Thread 3(2) Thread 3(1) Making 5 All Threads Started Thread 4(5) Thread 4(4) Thread 4(3) Thread 4(2) Thread 4(1) Thread 5(5) Thread 5(4) Thread 5(3) Thread 5(2) Thread 5(1)

57 Avec yield() public class SimpleThread extends Thread { private int countDown = 5; private static int threadCount = 0; private int threadNumber = ++threadCount; public SimpleThread() { System.out.println("Making " + threadNumber); } public void run() { while(true) { System.out.println("Thread " + threadNumber + "(" + countDown + ")"); if(--countDown == 0) return; yield(); } } du livre de Bruce Eckel

58 le résultat avec yield() Making 1 Making 2 Making 3 Making 4 Making 5 Thread 1(5) Thread 2(5) Thread 3(5) All Threads Started Thread 4(5) Thread 1(4) Thread 2(4) Thread 3(4) Thread 5(5) Thread 4(4) Thread 1(3) Thread 2(3) Thread 3(3) Thread 5(4) Thread 4(3) Thread 1(2) Thread 2(2) Thread 3(2) Thread 5(3) Thread 4(2) Thread 1(1) Thread 2(1) Thread 3(1) Thread 5(2) Thread 4(1) Thread 5(1)

59 Je veux terminer mon travail ! Joining a thread –One thread may call join( ) on another thread to wait for the second thread to complete before proceeding. –If a thread calls t.join( ) on another thread t, –then the calling thread is suspended until the target thread t finishes (when t.isAlive( ) is false). You may also call join( ) with a timeout argument so that if the target thread doesnt finish in that period of time, the call to join( ) returns anyway.

60 Timer : Simple et Utile Pragmatiquement –Un Thread pour repousser une action dans le temps Dans 3 secondes, si lutilisateur na pas bougé sa souris, afficher un popup disans « Ce bouton sert à quitter le document » –Un Thread pour répéter une action régulièrement Tous les 0.5 secondes, redessine la barre de progression. Pour ces cas simple, pas besoin de faire des Threads compliqués : Utiliser un Timer ! Tutorial Java ->Essential ->Threads ->Timer –Déclencher une action tout en continuant –Déclencher une action après n millisecondes –Déclencher des actions toutes les p millisecondes

61 Exemple Tutorial Java ->Essential ->Threads ->Timer –Déclencher une action tout en continuant –Déclencher une action après n millisecondes –Déclencher des actions toutes les p millisecondes


Télécharger ppt "Programmation Objet en JAVA Cours 8 Thread, Multi-thread, synchronisation,..."

Présentations similaires


Annonces Google