Le multitâche en Java q Objectifs ♦ Faire plus d’une chose à la fois Application multi tâches Systèmes d’exploitation WindowNT et successeurs, Unix, Linux, … Application interactive Calcul Dialogue (ascenseurs, menus, …) ♦ Aller plus vite Calcul parallèle Résolution de matrice ♦ Faire tourner des tâches en fond Sauvegarde automatique régulière Consultation périodique pour remise à jour File manager Animation, son, … Java – Les Threads - 19/11/03 1 L’informatique temps réel en Java q Programmation par Tâches ♦ Notion d’événements ♦ Synchronisation de tâches ♦ Rendez vous ♦ Priorités des tâches q La réponse du langage Java ♦ La notion de Thread ♦ Le multi Threading (multi tâches) q Les problèmes liés à Java ♦ Pas de contrôle précis du planning de déclenchement des tâches Des tâches intempestives Ramasse miettes Des lenteurs Java – Les Threads - 19/11/03 2 La notion de Thread q Rappel : un programme séquentiel mono tâche ♦ Un début, une séquence d’exécution, une fin Un pointeur de programme ♦ Une pile de mémoire pour gérer les appels q Un programme multi tâches ♦ Tâche = Thread ♦ Un ou plusieurs Threads tournent dans un programme ♦ Chaque Thread dispose de : Un début, une séquence d’exécution, une fin Son contexte d’exécution Un pointeur de programme Une pile mémoire Une priorité Java – Les Threads - 19/11/03 3 Comment créer des Threads en Java q Les Threads sont des objets ♦ classe java.lang.Thread ♦ Les instances de Thread sont des tâches Par exemple : Thread t1 = new Thread("t1"); Thread t2 = new Thread("t2"); Thread t3 = new Thread("t3"); t1.start(); t2.start(); t3.start(); Les 3 tâches, t1, t2, et t3 s’exécutent simultanément q Les tâches implémentent l’interface Runnable interface java.lang.Runnable => méthode run() q Exécution simultanée ? Un seul processeur Temps partagé Priorité des tâches (ici la même pour toutes les tâches) Java – Les Threads - 19/11/03 4 Créer une tâche en étendant la classe Thread La création d’une tâche passe par : La dérivation de la classe Thread, La surcharge de la méthode run() de la classe Thread Le lancement du Thread par la méthode start() qui appelle la méthode run(). q Un exemple L’exemple suivant montre le parallélisme en Java à l'aide d'une classe qui dérive de la classe Thread. La classe pour le programme principal public class MultiThreadDemo0 { public static void main(String args[]) { Joueur j1 = new Joueur("j1"); Joueur j2 = new Joueur ("j2"); Joueur j3 = new Joueur ("j3"); j1.start(); j2.start(); j3.start(); } } i Un seul programme, 3 tâches s’exécutant « simultanément » Java – Les Threads - 19/11/03 5 Classe héritant de la classe Thread class Joueur extends Thread { private String nom; public Joueur (String nom) { this.nom = nom; } // Lancement de Thread public void run(){ while (true) { // Exécution infinie du Thread try { int temps = (int)(Math.random()*5000); System.out.println(nom+" dort pendant "+ temps); sleep(temps); } catch(InterruptedException e) {} } } } Java – Les Threads - 19/11/03 6 Compte rendu d’exécution Z:\Thread2>java j1 dort pendant j2 dort pendant j3 dort pendant j1 dort pendant j2 dort pendant j2 dort pendant j3 dort pendant j1 dort pendant j2 dort pendant j1 dort pendant j3 dort pendant j2 dort pendant j3 dort pendant j3 dort pendant j3 dort pendant j1 dort pendant j2 dort pendant j1 dort pendant j3 dort pendant j2 dort pendant j3 dort pendant j3 dort pendant j2 dort pendant MultiThreadDemo0 134 2254 4013 4304 773 2868 2868 1589 1516 2884 1461 2224 525 7 2640 2215 2414 4193 770 1473 743 2432 3145 Java – Les Threads - 19/11/03 7 Thread en implantant l’interface Runnable Une autre manière de mettre en œuvre le parallélisme en Java : Implémenter l’interface Runnable Définir la méthode run() dans la classe implémente l’interface. La méthode run() comportera les instructions de l'exécution du thread. q Un exemple L’exemple suivant montre le parallélisme en Java à l'aide d'une classe qui dérive de l’interface Runnable. La classe qui contient le programme principal public class MultiThreadDemo1{ public static void main(String args[]) { Joueur j1 = new Joueur("j1"); Joueur j2 = new Joueur("j2"); Joueur j3 = new Joueur("j3"); j1.partir(); j2.partir(); j3.partir(); } } i Pas de différence à ce niveau avec la démarche précédente Java – Les Threads - 19/11/03 8 La classe qui implémente l’interface Runnable class Joueur implements Runnable { private String nom; private Thread t; // Déclaration du thread public Joueur(String nom) { this.nom = nom; // Instantiation du thread associée à la classe t = new Thread(this); } // Lancement du Thread. public void partir() { t.start();// Appelle run() de cette classe. } public void run(){ while (true) { try { int temps = (int)(Math.random()*5000); System.out.println(nom+" dort pendant "+ms); t.sleep(temps); // Appel de la fonction sleep } catch(InterruptedException e) {} } } } Java – Les Threads - 19/11/03 9 Le cycle de vie d’un Thread Java – Les Threads - 19/11/03 10 Les priorités Java – Les Threads - 19/11/03 11 La synchronisation des Thread La synchronisation est un concept qui permet lors du parallélisme, de contrôler les threads les uns par rapport aux autres. Elle assure l’ordre d’exécution des différents Thread. En java, on peut soit synchroniser une méthode, soit synchroniser un objet. Java – Les Threads - 19/11/03 12 Méthode synchronized La synchronisation sur une méthode consiste à partager une méthode qui sera synchronisée. q Un exemple 4 joueurs partagent une seule balle. Ils ne peuvent jouer que lorsqu’ils possèdent la balle. Lorsqu’ils ne jouent pas, ils attendent la balle. public class SynchroDemo0 { public static void main(String args[]){ Balle b = new Balle(); Joueur j1 = new Joueur("Joueur1",b); Joueur j2 = new Joueur("Joueur2",b); Joueur j3 = new Joueur("joueur3",b); Joueur j4 = new Joueur("Joueur4",b); j1.start(); j2.start(); j3.start(); j4.start(); } } Java – Les Threads - 19/11/03 13 Synchronisation par une méthode : la classe Balle public class Balle { public synchronized void prendre(Joueur jr) { try { int temps = (int)(Math.random()*5000); System.out.println("le joueur "+jr.nom+" prend et garde la balle pendant "+temps+" ms;"); jr.sleep(temps); } catch(InterruptedException e) {} } } public class Joueur extends Thread { String nom; Balle laBalle ; public Joueur(String nom,Balle b) { this.nom = nom; this.laBalle = laBalle ; } public void run() { while(true) { // Appel à la méthode synchronisée laBalle.prendre(this); } } } Java – Les Threads - 19/11/03 14 Compte rendu d’exécution le joueur Joueur1 pendant 2218 ms; le joueur Joueur2 pendant 4882 ms; le joueur joueur3 pendant 2228 ms; le joueur Joueur4 pendant 2793 ms; le joueur Joueur1 pendant 1463 ms; le joueur Joueur2 pendant 1495 ms; le joueur joueur3 pendant 4035 ms; le joueur Joueur4 pendant 4852 ms; le joueur Joueur1 pendant 605 ms; le joueur Joueur2 pendant 4252 ms; le joueur joueur3 pendant 465 ms; le joueur Joueur4 pendant 3259 ms; Java – Les Threads - 19/11/03 prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle prend et garde la balle 15 Objet synchronized Le but de cette méthode est d’utiliser un objet commun à tous les Threads. La synchronisation sera faite sur cet objet. public class Balle {} public class Joueur extends Thread { private Balle laBalle; private String nom; public Joueur(String nom,Balle b) { this.nom = nom; this.laBalle = b} public void run(){ while(true) { // Bloc synchronized qui est exécuté lorsque // l'objetBalle est relâché synchronized(laBalle) { try { int temps = (int)(Math.random()*5000); System.out.println("le joueur "+nom+" garde la balle pendant "+temps+" ms;"); sleep(temps); } catch(InterruptedException e) {} } // Fin du bloc synchronized: objet Balle relâché, // donc un autre thread peut s'en servir } } } Java – Les Threads - 19/11/03 16 Compte rendu d’exécution le le le le le le le joueur joueur joueur joueur joueur joueur joueur Joueur1 Joueur2 joueur3 Joueur4 Joueur1 Joueur2 joueur3 garde garde garde garde garde garde garde Java – Les Threads - 19/11/03 la la la la la la la balle balle balle balle balle balle balle pendant pendant pendant pendant pendant pendant pendant 1617 ms; 101 ms; 1724 ms; 707 ms; 504 ms; 3694 ms; 3065 ms; 17