Notion de thread (1/2)



Documents pareils
Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

Synchro et Threads Java TM

Threads. Threads. USTL routier 1

J2SE Threads, 1ère partie Principe Cycle de vie Création Synchronisation

NFP 121. Java et les Threads. Présentation : Thierry Escalarasse Mai 2007

INITIATION AU LANGAGE JAVA

Un ordonnanceur stupide

Introduction : les processus. Introduction : les threads. Plan

Exercices INF5171 : série #3 (Automne 2012)

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Introduction à la programmation concurrente

4. Outils pour la synchronisation F. Boyer, Laboratoire Lig

PIGOURIER Vincent ANNEE SPECIALE 99/00 RAPPORT DE PROJET : LES THREADS JAVA. Responsable : Serge Rouveyrol

Apprendre la Programmation Orientée Objet avec le langage Java (avec exercices pratiques et corrigés)

TD2 Programmation concurrentielle

Programmation Orientée Objet - Licence TIS CM8/9. Rappel sur la séance précédente. Lancelot Pecquet Lancelot.Pecquet@math.univ-poitiers.

Sixième partie. Programmation multi-activités Java & Posix Threads. Généralités Java Threads POSIX Threads Autres approches

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Initiation à JAVA et à la programmation objet.

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Support de cours Java

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Problèmes liés à la concurrence

4. Outils pour la synchronisation F. Boyer, Laboratoire Sardes

Remote Method Invocation Les classes implémentant Serializable

LOG4430 : Architecture et conception avancée

Corrigé des exercices sur les références

Les Threads. Sommaire. 1 Les Threads

Héritage presque multiple en Java (1/2)

On appelle variable condition une var qui peut être testée et

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Programmation concurrente et Java. Les Threads en Java : une première approche

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Programmer en JAVA. par Tama

RMI le langage Java XII-1 JMF

Java Licence Professionnelle CISII,

Cours 1: Java et les objets

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

Programmation par les Objets en Java

Une introduction à la technologie EJB (2/3)

Chapitre 10. Les interfaces Comparable et Comparator 1

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Cours de Systèmes d Exploitation

La JVM. La machine virtuelle Java. La JVM. La JVM

ACTIVITÉ DE PROGRAMMATION

Java avancé Objectifs. version support 1.2

Guide d'installation. Release Management pour Visual Studio 2013

JADE : Java Agent DEvelopment framework. Laboratoire IBISC & Départ. GEII Université & IUT d Evry nadia.abchiche@ibisc.univ-evry.

Généralités sur le Langage Java et éléments syntaxiques.

Projet gestion d'objets dupliqués

Auto-évaluation Programmation en Java

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Calcul Parallèle. Cours 5 - JAVA RMI

Développement Logiciel

Programmation avec des objets : Cours 7. Menu du jour

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Cours 2: Exclusion Mutuelle entre processus (lourds, ou légers -- threads)

Pour plus de détails concernant le protocole TCP conférez vous à la présentation des protocoles Internet enseignée pendant.

Java - la plateforme

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Une introduction à Java

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Programmation d Applications Concurrentes et Distribuées (INF431)

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

as Architecture des Systèmes d Information

Programmation Par Objets

École Polytechnique de Montréal. Département de Génie Informatique et Génie Logiciel. Cours INF2610. Contrôle périodique.

Programmation Concurrente. Rémi Forax

Diagramme de classes

Introduction aux systèmes temps réel. Iulian Ober IRIT

Plan du cours. Historique du langage Nouveautés de Java 7

TP Composants Java ME - Java EE. Le serveur GereCompteBancaireServlet

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Remote Method Invocation (RMI)

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Premiers Pas en Programmation Objet : les Classes et les Objets

Cours Programmation Système

Chapitre 2. Classes et objets

Desktop Intégration. Rémi Forax

Les processus légers : threads. Système L3, /31

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Projet de Veille Technologique

Communication inter-processus (IPC) : tubes & sockets. exemples en C et en Java. F. Butelle

Langage et Concepts de Programmation Objet. 1 Attributs et Méthodes d instance ou de classe. Travaux Dirigés no2

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique

Java c est quoi? Java. Java. Java : Principe de fonctionnement 31/01/ Vue générale 2 - Mon premier programme 3 - Types de Programme Java

TD/TP PAC - Programmation n 3

PROGRAMMATION EVENEMENTIELLE sur EXCEL

Projet de programmation (IK3) : TP n 1 Correction

Cours de Génie Logiciel

I-JVM: une machine virtuelle Java pour l isolation de composants dans OSGi

Package Java.util Classe générique

Gestion distribuée (par sockets) de banque en Java

Objets et Programmation. origine des langages orientés-objet

Exercices sur les interfaces

Classe ClInfoCGI. Fonctions membres principales. Gestion des erreurs

Java. Mémoire présenté à la Faculté des études supérieures de l'université Laval pour l'obtention du grade de Maître ès Sciences (MSc.

Transcription:

Notion de thread (1/2) La machine virtuelle java (JVM) permet d'exécuter plusieurs traitements en parallèle (en pratique, ils s'exécutent par tranche et en alternance sur le processeur). Ces traitements sont gérés par des threads of control (fil de contrôle), ou plus simplement threads. Les threads Java sont des processus légers : ils partagent un ensemble de codes, données et ressources au sein d'un processus lourd qui les héberge (ce processus est la JVM). Avantages des processus légers par rapport aux processus système : - rapidité de lancement et d'exécution - partage des ressources système du processus englobant - simplicité d'utilisation 1 Notion de thread (2/2) Intérêts d'une application multi-threads : - gérer l'exécution de traitements longs sans bloquer les autres exemples : - calculs, affichage et gestion des interactions dans une interface graphique - lancer des programmes démons qui tournent en tâche de fond - lancer plusieurs exécutions du même code simultanément sur différentes données exemples : - répondre à plusieurs requêtes en même temps dans un serveur - traiter deux flux sonores en parallèle - simuler le parallèlisme nécessaire à certaines classes d'applications - exploiter la structure multi-processeurs des ordinateurs modernes? Inconvénients d'une application multi-threads : - il faut gérer les problèmes de synchonisation entre threads - une telle application est difficile à écrire et à débogger 2

Thread et Runnable (1/3) En Java, un thread est une instance de la classe Thread qui implémente l'interface Runnable dont la méthode run() décrit le traitement à lancer. public interface Runnable{ public void run(); Un thread est crée en sous classant la classe Thread et en redéfinissant sa méthode run(), ou en instanciant le thread avec un objet Runnable. new Thread(new Runnable(){ ); Un Thread qui n'est plus référencé n'est pas détruit par le garbage collector car il est enregistré par un contrôleur d'exécution. Le thread principal est celui de la méthode main. 3 Thread et Runnable (2/3) public class Perroquet extends Thread{ private String nom; public Perroquet(String nom){ this.nom = nom; for(i=0;i<3;i++){ System.out.println(nom + " est content"); Thread.sleep(500); catch(interruptedexception e){system.out.println(e.getmessage()); Thread t1 = new Perroquet("jacko"); Thread t2 = new Perroquet("jacki"); 4

Thread et Runnable (3/3) public class Perroquet implements Runnable{ private String nom; public Perroquet(String nom){ this.nom = nom; for(i=0;i<3;i++){ System.out.println(nom + " est content"); Thread.sleep(500); catch(interruptedexception e){system.out.println(e.getmessage()); Thread t1 = new Thread(new Perroquet("jacko")); Thread t2 = new Thread(new Perroquet("jacki")); on peut créer plusieurs threads différents sur un même objet Runnable Perroquet p = new Perroquet("jacko"); Thread t1 = new Thread(p); Thread t2 = new Thread(p); 5 Vie et mort d'un thread (1/2) destroy, resume, suspend et stop sont des méthodes agissant sur l'état d'un thread, mais qui peuvent poser des problèmes de blocage ou de mauvaise terminaison et sont donc désapprouvées. 6

Vie et mort d'un thread (2/2) Activation : la méthode start() appelle la méthode run() (start() n'est pas bloquante dans le thread appelant). Destruction : elle intervient quand la méthode run() se termine. Il est possible d'interrompre le thread en utilisant la méthode interrupt() qui crée une InterruptedException si le thread est en attente. public class MonThread extends Thread{ // traitement, avec des périodes de sommeil et/ou d'attente catch(interruptedexception e){ // libération propre des ressources // autre traitement 7 Sommeil d'un thread (1/2) Thread.sleep(long millis) est une méthode de classe qui met le thread courant en sommeil un certain nombre de millisecondes. Appelée dans la méthode run() du thread, elle le met en sommeil. Si cette méthode est appelée dans du code synchronisé (synchronized) le thread ne perd pas le moniteur (voir plus loin). L'exécution d'un thread peut également être suspendue par des processus bloquant (entrée/sortie en particulier) getstate() renvoie l'état du thread, isalive() est vrai si le thread est actif ou endormi 8

Sommeil d'un thread (2/2) public class TestSleep extends Thread{ public TestSleep(String name){super(name); System.out.println(this.getName()+" a ete lance"); Thread.sleep(100); System.out.println(this.getName()+" est termine"); catch(interruptedexception e){ System.out.println(this.getName()+" a ete interrompu"); public static void main(string arg[]){ TestSleep mt = new TestSleep("Toto"); mt.start(); Thread.sleep(100); mt.interrupt(); catch(interruptedexception ie){ De temps en temps, Toto terminera normalement, d'autres fois il sera interrompu. 9 La classe Timer La classe java.util.timer permet de lancer un processus une ou plusieurs fois en précisant des délais. Un Timer gère les exécutions d'une instance de TimerTask, classe qui implémente Runnable. public class ExempleTimer extends TimerTask{ System.out.println("je m'execute"); Thread.sleep(500); catch(interruptedexception e){system.out.println(e.getmessage()); Timer t = new Timer(); // la tâche se répètera toutes les 2s et démarre dans 1s t.schedule(new ExempleTimer(),1000,2000); Date d = new Date(); d.settime(d.gettime()+10000); // la tâche démarre dans 10s t.schedule(new ExempleTimer(),d); 10

Priorités entre threads (1/2) Une valeur de priorité est affectée à chaque thread et détermine sa priorité d'accès au temps CPU. Mais la JVM n'assure pas le time slicing : le temps CPU n'est pas forcément partagé équitablement entre threads de même priorité par l'os. La priorité est modifiée par setpriority(int i) et accédée par int getpriority(): Thread t1 = new Thread(new Perroquet("jacko")); Thread t2 = new Thread(new Perroquet("jacki")); t1.setpriority(thread.max_priority); t1.start(); t2.start(); 11 Priorités entre threads (2/2) La méthode de classe Thread.yield() suspend l'exécution du thread qui est en train de s'exécuter pour donner la main à un autre. - le thread en train de s'exécuter n'est pas mis en sommeil, il est toujours dans la liste des threads actifs - l'appel de cette méthode peut redonner la main au thread courant! La méthode setdaemon(boolean on) appelée avant start() permet de faire du thread un démon, processus de basse priorité qui tourne en tâche de fond. exemple : le garbage collector 12

Synchronisation Les threads s'exécutant en parallèle sur des données qui peuvent être communes, il faut gérer des conflits d'accès et des problèmes de synchronisation entre threads. La synchronisation peut consister à entremêler les exécutions des threads de manière à ce qu'ils n'accèdent à certaines données ou à certains morceaux de code que chacun à leur tour alternativement. Une méthode plus simple est la synchronisation sur terminaison : on veut qu'un morceau de code ne s'exécute qu'après qu'un thread donné ait terminé. La méthode join() permet une telle synchronisation. exemple : on veut que jacko attende que jacki ait fini de parler pour prendre la parole 13 Synchronisation sur terminaison (1/2) public class Perroquet extends Thread{ private String nom; private Perroquet interlocuteur; private boolean premier; public Perroquet(String nom, boolean b){ this.nom = nom; this.premier = b; public void setinterlocuteur(perroquet p){this.interlocuteur = p; if(!premier){ System.out.println("je vous écoute"); interlocuteur.join(); System.out.println("je vous réponds"); for(int i=0;i<3;i++){ System.out.println(nom + " est content"); Thread.sleep(500); catch(interruptedexception e){system.out.println(e.getmessage()); 14

Synchronisation sur terminaison (2/2) public class Test{ public static void main(string arg[]){ Perroquet p1 = new Perroquet("jacko",false); Perroquet p2 = new Perroquet("jacki",true); p1.setinterlocuteur(p2); p2.setinterlocuteur(p1); p1.start(); p2.start(); 15 La classe Executor Un java.util.concurrent.executor permet de gérer le lancement d'un ensemble de Runnable et la synchronisation sur terminaison. La classe java.util.concurrent.executors est une «usine» qui fabrique des instances de sous-classes d'executor. // exécution des threads dans une file ExecutorService ex = Executors.newSingleThreadExecutor(); ex.execute(new Runnable(){ public void run (){ ); Runnable r = new MonRunnable(); ex.execute(r); ex.shutdown(); La méthode Executors.newFixedThreadPool(int nbthreads) permet de lancer plusieurs threads en même temps mais en nombre limité. 16

Section critique (1/2) Un morceau de code est une section critique s'il est nécessaire de garantir qu'au plus un thread exécutera ce code à la fois public class Pile{ private Object[] tab;private int sommet; public Pile(int taille){ this.tab = new Object[taille]; this.sommet = -1; public void empile(object o) throws IndexOutOfBoundsException { if(this.sommet>=this.tab.length-1) throw new IndexOutOfBoundsException("Pile pleine"); else{ this.tab[this.sommet+1] = o; this.sommet ++; public Object depile() throws IndexOutOfBoundsException { if(this.sommet == -1) throw new IndexOutOfBoundsException("Pile vide"); else{ this.sommet --; return this.tab[this.sommet+1]; 17 public class Depileur extends Thread{ private Pile p; public Depileur(Pile p){ super(); this.p = p; Section critique (2/2) while(true){ System.out.println(p.depile()); Thread.sleep(10); catch(indexoutofboundsexception e){system.out.println(e.getmessage()); catch(interruptedexception e){system.out.println(e.getmessage()); public static void main(string ar[]){ Pile p = new Pile(10); for(int i = 0;i<10;i++) p.empile(new Integer(i)); Depileur d1 = new Depileur(p); Depileur d2 = new Depileur(p); d1.start(); d2.start(); 18

Moniteur Une ressource critique est une ressource qui ne doit être accédée que par un seul thread à la fois. exemples : variable globale, périphérique de l'ordinateur. En Java, il n'est pas possible de contrôler directement l'accès simultané à une variable, il faut l'encapsuler et contrôler l'exécution de l'accesseur correspondant. Un moniteur est un verrou qui ne laisse qu'un seul thread à la fois accéder à la ressource. En Java, tout objet peut jouer le rôle de moniteur. On pose un moniteur sur un bloc de code à l'aide du mot clé synchronized synchronized(objetmonitor){ //code en section critique 19 Moniteur en Java - un thread n'accède à la section critique que si le moniteur est disponible - un thread qui entre en section critique bloque l'accès au moniteur - un thread qui sort de section critique libère l'accès au moniteur - sleep ne fait pas perdre le moniteur (contrairement à wait) Attention : le moniteur ne doit pas être modifié dans la section critique! Si le verrou change, la synchronisation n'est plus garantie. synchronized(maliste) { maliste = new ArrayList<String>(); Méthodes synchronisées : on peut déclarer qu'une méthode est en section critique sur le moniteur this synchronized void methode() { //section critique void methode() { synchronized(this) { //section critique 20

Synchronisation sur moniteur wait() et notify() synchronisent des threads sur un moniteur : l'objet o sur lequel les méthodes sont appelées joue le rôle de moniteur le thread qui appelle la méthode o.wait() est placé dans le wait-set de o, perd le moniteur et attend il redeviendra actif dans un des cas suivants : si la méthode o.notify() est appelée et qu'il est choisi parmi les threads du wait-set (activation d'un des threads du wait-set, sélection plus ou moins aléatoire) si la méthode o.notifyall() est appelée (activation de tous les threads du wait-set) si la durée spécifiée pour le wait est écoulée (cas où wait(int timeout) est utilisée) Le thread qui appelle wait ou notify doit posséder le moniteur : synchronized(obj){ obj.wait(); catch(interruptedexception e){ synchronized(obj){ obj.notify(); catch(interruptedexception e){ 21 Synchronisation des accès à une file (1/2) public class File extends ArrayList<Object>{ public synchronized void enfiler(object o){ System.out.println("enfilage de " + o.tostring()); this.add(o); if(this.size()>=1){ this.notify(); catch(interruptedexception e){ public synchronized Object defiler(){ if(this.size()==0){ this.wait(); catch(interruptedexception e){ Object o = this.get(0); System.out.println("defilage de " + o.tostring()); this.remove(0); return o; 22

Synchronisation des accès à une file (2/2) public class Enfileur extends Thread{ private File f; private int cpt; public class Defileur extends Thread{ public Enfileur(File f){ this.f = f; this.cpt = 0; while(this.cpt < 20){ f.enfiler("element " + this.cpt); Thread.sleep(1000); this.cpt ++; catch(interruptedexception e){ private File f; public Defileur(File f){ this.f = f; while(true){ f.defiler(); 23 Synchronisation et POO La synchronisation est indépendante de l'héritage : - une méthode synchronisée peut être redéfinie dans une sous-classe sans être synchronisée. - une méthode non synchronisée peut être redéfinie et synchronisée dans une sousclasse. La synchronisation d'une méthode de classe se fait sur l'instance de Class représentant la classe. public class Machin{ public static synchronized m(){ 24

Sémaphore en Java (1/2) Un morceau de code est dit réentrant s'il peut être exécuté par plusieurs threads en même temps. Cela suppose que les données sur lesquelles travaille le code soient fournies par les threads. Il peut cependant être nécessaire de limiter le nombre de threads accédant au code. Un sémaphore permet d'autoriser plusieurs threads à accéder à du code réentrant. Le sémaphore gère un ensemble de permis, en nombre fixé, et accorde ces permis aux threads qui en font la demande. java.util.concurrent.semaphore implémente ce mécanisme : - Semaphore(int i) crée un sémaphore avec i permis initiaux - la méthode acquire() permet de requérir un permis et bloque le thread demandeur jusqu'à ce qu'un permis soit disponible ou que le thread soit interrompu. acquire(int) permet de requérir plusieurs permis. - la méthode release() augmente le nombre de permis disponibles de 1. release(int i) augmente le nombre de permis disponibles de i. - la méthode tryacquire() permet d'acquérir un permis mais n'est pas bloquante. 25 Sémaphore en Java (2/2) public class MonThread extends Thread{ private String s; private Semaphore sem; public MonThread(String s, Semaphore sem){this.s = s;this.sem = sem; sem.acquire(); System.out.println(s+" a un permis ("+sem.availablepermits()+" restants)"); Thread.sleep(10); sem.release(); System.out.println(s+" n'a plus de permis ("+sem.availablepermits()+" restants)"); catch(interruptedexception e){system.out.println(e.getmessage()); public static void main(string[] a){ Semaphore sem = new Semaphore(3); for(int i = 0;i<5;i++){ MonThread mt = new MonThread("toto"+i,sem); mt.start(); 26

La classe Lock (1/2) Un java.util.concurrent.locks.lock permet de réaliser des moniteurs complexes. Les Lock permettent une synchonisation plus souple, mais plus exigante que les blocs synchronized. En particulier, il ne faut pas oublier d'ouvrir le verrou après l'avoir utilisé. Il est conseillé de mettre le code en section critique dans un try/finally, pour être sur de déverrouiller le Lock dans tous les cas. Lock l = new ReentrantLock(); l.lock(); //section critique finally{ l.unlock(); Un des avantages de Lock est la possibilité de tenter d'acquérir le verrou et s'il est déjà pris, de faire autre chose : méthode trylock() 27 La classe Lock (2/2) Des objets Condition peuvent être ajoutés au verrou pour faire de la synchronisation sur plusieurs verrous croisés. public class LockExample { private Lock lock = new ReentrantLock(); private Condition cond1 = lock.newcondition(); private Condition cond2 = lock.newcondition(); public void m() throws InterruptedException { lock.lock(); try { cond1.await(); cond2.signal(); finally { lock.unlock(); 28