Système d exécution Java

Documents pareils
Synchro et Threads Java TM

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

Un ordonnanceur stupide

Threads. Threads. USTL routier 1

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

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

Problèmes liés à la concurrence

Introduction : les processus. Introduction : les threads. Plan

INITIATION AU LANGAGE JAVA

Notion de thread (1/2)

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

Java Licence Professionnelle CISII,

Projet de programmation (IK3) : TP n 1 Correction

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

Premiers Pas en Programmation Objet : les Classes et les Objets

Programmer en JAVA. par Tama

Introduction à la programmation concurrente

Corrigé des exercices sur les références

TD2 Programmation concurrentielle

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

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

Développement Logiciel

Programmation par les Objets en Java

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

TP1 : Initiation à Java et Eclipse

Auto-évaluation Programmation en Java

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

Package Java.util Classe générique

Environnements de développement (intégrés)

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

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

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

as Architecture des Systèmes d Information

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

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

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

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

Programme Compte bancaire (code)

TD/TP PAC - Programmation n 3

RMI le langage Java XII-1 JMF

Une introduction à Java

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Programmation avec des objets : Cours 7. Menu du jour

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

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

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

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

Cours 1: Java et les objets

PROGRAMMATION PAR OBJETS

Calcul Parallèle. Cours 5 - JAVA RMI

Remote Method Invocation Les classes implémentant Serializable

TD3: tableaux avancées, première classe et chaînes

ACTIVITÉ DE PROGRAMMATION

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

Langage Java. Classe de première SI

Tp 1 correction. Structures de données (IF2)

Programmation Objet Java Correction

Projet gestion d'objets dupliqués

TD/TP PAC - Programmation n 3

Design patterns. Design patterns - définition. Design patterns - avantages

Une introduction à la technologie EJB (2/3)

Programmation Par Objets

Chapitre 10. Les interfaces Comparable et Comparator 1

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

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

Java Licence Professionnelle CISII,

ALGORITHMIQUE ET PROGRAMMATION ORIENTEE OBJET

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

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

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

Développement mobile MIDP 2.0 Mobile 3D Graphics API (M3G) JSR 184. Frédéric BERTIN

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

Programmation d Applications Concurrentes et Distribuées (INF431)

Remote Method Invocation (RMI)

Initiation à JAVA et à la programmation objet.

Modèle à composants. Daniel Hagimont. IRIT/ENSEEIHT 2 rue Charles Camichel - BP TOULOUSE CEDEX 7. Remerciements

Dis papa, c est quoi un bus logiciel réparti?

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

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

Corrigés des premiers exercices sur les classes

Programmation Internet en Java

Serveur d'archivage 2007 Installation et utilisation de la BD exist

OpenPaaS Le réseau social d'entreprise

Java DataBaseConnectivity

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Derrière toi Une machine virtuelle!

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

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

Java RMI. Arnaud Labourel Courriel: Université de Provence. 8 mars 2011

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

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

Par Laurent DESECHALLIERS. Mastère Spécialisé en Management de Projets en Milieu Industriel. CESI de Rouen Promotion 2002/2003.

Apprendre Java en 154 minutes

TP3. Mail. Attention aux fausses manoeuvres lors de ce TP vous pouvez endommager votre mail sur ouindose.

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

TP, première séquence d exercices.

La persistance des données dans les applications : DAO, JPA, Hibernate... COMPIL 2010 francois.jannin@inp-toulouse.fr 1

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

Cours de Systèmes d Exploitation

Transcription:

Programmation Réseau Système d exécution Java Jean-Baptiste.Yunes@univ-paris-diderot.fr! UFR Informatique! 2013-2014

Les Threads on rappelle qu un processus est un programme (de nature statique) en cours d exécution (de nature dynamique) son exécution nécessite un environnement (espace d adressage, objets E/S, etc.) un thread est un fil d exécution dans un processus donné un processus peut être multi-threadé (mais au minimum mono-threadé) 2

un fil d exécution est distinct des autres et a pour attributs : un point courant d exécution (pointeur d instruction, ou PC program counter) une pile d exécution (stack) on notera qu un Thread partage tout le reste de l environnement avec les autres Threads qui lui sont concurrents dans le même processus 3

La JVM de Java est multi-threadé et offre au programmeur la possibilité de gérer des threads à sa guise il n est pas précisé comment ces threads sont pris en charge par le système sous-jacent On notera au passage que Java permet aussi de manipuler des processus (lesquels sont pris en charge par le système) il n y a pas de notion processus dans Java luimême,un processus est un objet du système hôte 4

L environnement d exécution en Java L environnement d exécution d une JVM est disponible dans la JVM elle-même sous la forme d un objet de type java.lang.runtime attention, il n existe qu un seul exemplaire d un tel objet (Singleton); impossible de créer un objet de cette classe L instance unique peut être retrouvée par appel à la méthode statique Runtime getruntime(); 5

de nombreuses méthodes sont disponibles dans la classe Runtime entre autres celles permettant de demander au système hôte de créer un processus concurrent (l exécution d un programme en dehors de la JVM elle-même) c est la famille des méthodes Process exec( ); voir la documentation 6

Les processus en Java les processus dont l exécution (externe) a été commandée par une JVM sont représentés dans celle-ci sous la forme d objet java.lang.process ces objets permettent de communiquer avec les processus externes correspondants se synchroniser avec leur exécution 7

on peut obtenir les flux d entrée et sorties du processus externe avec : InputStream geterrorstream(); InputStream getoutputstream(); OutputStream getintputstream(); une entrée du processus correspond à une sortie depuis la JVM et vice-versa Process JVM in err out Processus 8

il est possible de se synchroniser avec l exécution du processus externe : int exitvalue(); int waitfor(); qui renvoient la valeur de terminaison du processus externe, en mode bloquant avec waitfor() et nonbloquant avec exitvalue() 9

Les threads en Java le mécanisme est plus complexe que celui des processus car il est interne au système Java il repose sur deux types d objets les Runnables, qui représentent des objets contenant du code qui servira de code principal (équivalent du main pour les threads); la nature statique d une exécution les Threads, qui représentent l exécution ellemême; la nature dynamique d une exécution 10

à tout Thread doit être associé un Runnable le point d entrée du code qu il exécutera bien entendu, à un Runnable donné il est possible d attacher autant de Threads que l on désire 11

java.lang.runnable il s agit d une interface qui ne déclare qu une seule méthode à implémenter : void run() lorsqu un Thread démarrera, son exécution débutera par un appel à la méthode run du Runnable qui lui est attaché terminera lorsque cet appel initial terminera 12

java.lang.thread les Threads Java ont plusieurs attributs String name [rw] : son nom long id [ro] : son identité int priority [rw] : sa priorité (les Threads sont ordonnancés à l aide de cette priorité) boolean daemon [rw] : son mode d exécution (démon ou non, voir plus loin) 13

Thread.State state [ro] : son état parmi NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED sa pile (mais dont on ne peut qu observer la trace) son groupe de Thread quelques autres attributs mineurs 14

les états possibles d un thread et l automate de transition sont : bpurcell.org 15

Point sur la terminaison d une JVM on indique généralement qu un programme Java s arrête lorsqu on sort du main un programme ne s arrête pas, seul un processus s arrête (abus de langage très commun) mais surtout il ne suffit pas sortir du main, encore faut-il sortir du premier appel au main (il est possible de faire des appels récursifs à main) mais en plus, il faut attendre que TOUS les Threads qui ne sont pas démons s arrêtent 16

il existe au moins un Thread démon : le garbage collector il en existe souvent un autre : le Thread de l interface graphique 17

le contrôle de l exécution d un Thread s effectue à travers les méthodes suivantes : void start(), qui permet de démarrer le Thread (il va alors appeler la méthode run() du Runnable associé) void join(), qui permet d attendre que le Thread s arrête 18

void interrupt(), qui permet de positionner le statut du Thread à interrompu ce qui n a aucun effet immédiat direct, sauf terminer certains appels en cours ou permettre au Thread concerné de savoir qu un autre Thread souhaite l interrompre Important : il n existe pas d autre technique pour arrêter un Thread que de se débrouiller pour qu il sorte de son premier appel à run() 19

la classe Thread possède plusieurs méthodes statiques : Thread currentthread(), qui permet de récupérer l objet Thread courant (le «this» du système de Thread) boolean interrupted(), qui permet de déterminer si le Thread courant a reçu une demande d interruption 20

void sleep(long ms) void sleep(long ms,long ns) qui permettent au Thread courant de renoncer à son exécution pour la durée exprimée (au minimum) void yield(), qui permet au Thread courant de renoncer à la suite de son quota d exécution et de reprendre une place dans l ordonnanceur 21

la classe Thread possède plusieurs constructeurs, dont les plus utiles permettent de lui associer un Runnable les deux constructeurs les plus fréquemment employés sont : Thread(Runnable) Thread(Runnable,String) 22

class MyCode implements Runnable { public void run() { int N = (int)(math.random()*5); for (int i=0; i<10000*n; i++) { System.out.println( Thread.currentThread().getName() +" i="+i); 23

public class Example { public static final int N = 20; public static void main(string []args) { MyCode code = new MyCode(); Thread []t = new Thread[N]; // création des N threads for (int i=0; i<n; i++) t[i]=new Thread(code,"T"+i); // lancement des N threads for (int i=0; i<n; i++) t[i].start(); // attente de la terminaison des N threads for (int i=n-1; i>=0; i--) { try { t[i].join(); catch(interruptedexception e) { System.out.println("Terminaison de "+t[i].getname()); System.out.println("tout est fini "); 24

il est à noter qu un Thread implémente l interface Runnable par une méthode run() qui ne fait rien ainsi on peut dériver la classe Thread et redéfinir la méthode run() afin d obtenir un objet Thread qui exécute un code qu il contient lui-même 25

Le(s) problème(s) de la concurrence class Compteur { private int valeur; public Compteur() { valeur = 0; public int getvaleur() { return valeur; public void setvaleur(int v) { valeur=v;! class MyCode implements Runnable { private Compteur c; public MyCode(Compteur c) { this.c = c; public void run() { for (int i=0; i<100000000; i++) { c.setvaleur(c.getvaleur()+1); 26

public class Example { public static final int N = 20; public static void main(string []args) { Compteur c = new Compteur(); MyCode code = new MyCode(c); Thread []t = new Thread[N]; for (int i=0; i<n; i++) t[i] = new Thread(code,"T["+i+"]"); for (int i=0; i<n; i++) t[i].start(); for (int i=0; i<n; i++) { try { t[i].join(); catch(interruptedexception e) { System.out.println("tout est fini "); System.out.println("Le compteur est égal à "+ c.getvaleur()); 27

1.716.791.363 20x100.000.000!!! 28

le problème est la non-atomicité de l opération d incrémentation du compteur le compteur est une ressource à laquelle les Threads accèdent concurremment T i prend la valeur disons v T i calcule v+1 T i passe la main à T i+1 T i+1 prend la valeur (c est encore v) T i+1 calcule v+1 T i+1 range la valeur v+1 T i+1 passe la main à T i T i range la valeur v+1 (à ce point les deux ont bien incrémenté chacun une fois, le malheur est qu ils ne se sont pas entendus pour le faire correctement) 29

Principe en programmation concurrente : on ne doit jamais faire aucune supposition sur l ordonnancement des exécutions par conséquent, il faut être offensif : prendre des précautions afin d éviter les problèmes défensif : attendre que le problème arrive pour le corriger 30

dans le cas précédent (celui du compteur) la solution est, par exemple, de rendre atomique la suite d opérations concernée on veut éviter de ne faire qu une partie de la suite d opérations : prendre la valeur, ajouter un, stocker le résultat une telle suite d opération est appelée une section critique on souhaite donc contrôler quels sont les Threads autorisés à entrer dans la section critique (penser à un sas, un portillon de contrôle) 31

le mécanisme usuel permettant de contrôler l entrée d une section critique est le verrou qui assure une propriété d exclusion mutuelle un verrou est posé avant l entrée en section critique et déposé ensuite la pose assure qu une seule demande ne peut être effectivement servie, les autres demandes sont placées en attente en Java il existe le mot-clé synchronized qui permet de verrouiller une section critique 32

deux utilisations possible de synchronized on peut verrouiller une méthode entière, auquel cas le mot-clé est employé dans la signature de la méthode on peut verrouiller un bloc de code en particulier par emploi de synchronized(o) { où o est l objet (de type quelconque) représentant le verrou 33

une méthode synchronisée synchronized méthode( ) { correspond exactement à méthode( ) { synchronized(this) { 34

class MyCode implements Runnable { private Compteur c; public MyCode(Compteur c) { this.c = c; public void run() { for (int i=0; i<100000000; i++) { synchronized(c) { c.setvaleur(c.getvaleur()+1); Attention à ne pas «synchroniser» n importe quoi Note : on remarquera qu une forte pénalité est appliquée à l exécution; les verrous ont un coût non négligeable Il est en général difficile de cerner la bonne granularité 35

Un autre problème de concurrence une section critique n est pas toujours, pour son bon fonctionnement, isolée du reste de l application en particulier, on peut vouloir garantir l unicité en section critique mais aussi assurer une interdépendance entre sections critiques le problème des producteurs/consommateurs 36

songeons au dynamisme d une structure tripartite : les producteurs produisent des objets et les stockent le stockage possède une capacité limitée les consommateurs retirent des objets du stockage pour les utiliser à leur propre fin on peut remarquer qu il s agit d un modèle de communication à canal de capacité limitée 37

le problème est dû aux vitesses relatives des opérations de consommation et production : si les producteurs sont plus rapides que les consommateurs, il va falloir assurer que lorsque le stockage est plein, la chaîne de production soit mise en attente... si les consommateurs sont plus rapides que les producteurs, il va falloir assurer l attente des consommateurs lorsque le stockage est vide 38

class Produit { private String nom; public Produit(String nom) { this.nom = nom; public String tostring() { return nom; 39

class Stock { private Produit []lestock; private int niveaucourant; private static final int capacitémaximale = 10; public Stock() { lestock = new Produit[capacitéMaximale]; niveaucourant = 0; public boolean addproduit(produit p) { if (niveaucourant==capacitémaximale) return false; lestock[niveaucourant++] = p; return true; public Produit removeproduit() { if (niveaucourant==0) return null; Produit p = lestock[niveaucourant-1]; lestock[--niveaucourant] = null; return p; 40

class Producteur extends Thread { private Stock stock; private String nomproduit; private Random random; Producteur(Stock stock,string nomproduit) { this.stock = stock; random = new Random(); this.nomproduit = nomproduit; public void run() { while (true) { Produit p = new Produit(nomProduit); try { Thread.sleep(random.nextInt(1000)+1000); catch(interruptedexception e) { if (!stock.addproduit(p)) { do { try { System.out.println("Producteur "+getid()+" plein"); Thread.sleep(random.nextInt(100)+100); catch(interruptedexception e) { while (!stock.addproduit(p)); System.out.println("Producteur "+getid()+" a rajoute "+p); 41

class Consommateur extends Thread { private Stock stock; private Random random; public Consommateur(Stock stock) { random = new Random(); this.stock = stock; public void run() { while (true) { try { Thread.sleep(random.nextInt(10000)+1000); catch(interruptedexception e) { Produit p = stock.removeproduit(); if (p==null) { do { try { System.out.println("Consommateur "+getid()+ " vide"); Thread.sleep(random.nextInt(100)+100); catch(interruptedexception e) { p = stock.removeproduit(); while (p==null); System.out.println("Consommateur "+getid()+" a enlevé "+p); 42

public class ProdCons { public static void main(string []args) { Stock stock = new Stock(); Producteur []p = new Producteur[2]; p[0] = new Producteur(stock,"banane"); p[1] = new Producteur(stock,"carambar"); p[0].start(); p[1].start(); Consommateur []c = new Consommateur[3]; c[0] = new Consommateur(stock); c[1] = new Consommateur(stock); c[2] = new Consommateur(stock); c[0].start(); c[1].start(); c[2].start(); 43

deux problèmes dans ce code : la non-atomicité des opérations d ajout et retrait du stock l attente active nous savons corriger le problème d atomicité de l accès au stock : synchronized 44

le problème subsistant est que le mécanisme mis en place encourage l attente active une boucle testant sans arrêt si la condition de continuation est vraie ou non... très consommatrice en ressources (CPU) pour empêcher cette attente active, nous avons un problème : nous souhaitons nous mettre en attente que la condition recherchée soit réalisée alors que nous avons la clé 45

pour se faire, nous allons employer les méthodes wait() et notify() héritées d Object wait() permet de relâcher un verrou que l on possède et de se mettre en attente jusqu a ce que quelqu un nous autorise à tenter de le reprendre notify() / notifyall() permet d autoriser un (resp. tous les) thread en attente de tenter de reprendre le verrou qu il possédait Attention : il FAUT déjà détenir le verrou pour effectuer ces opérations 46

class Stock { private Produit []lestock; private int niveaucourant; private static final int capacitémaximale = 10; public Stock() { lestock = new Produit[capacitéMaximale]; niveaucourant = 0; public synchronized void addproduit(produit p) { while (niveaucourant==capacitémaximale) { System.out.println("plein!"); try { wait(); catch(interruptedexception e) { lestock[niveaucourant++] = p; notifyall(); // to be continued 47

public synchronized Produit removeproduit() { while (niveaucourant==0) { System.out.println("vide!"); try { wait(); catch(interruptedexception e) { Produit p = lestock[niveaucourant-1]; lestock[--niveaucourant] = null; notifyall(); return p; // fin classe Stock 48

class Producteur extends Thread { private Stock stock; private String nomproduit; private Random random; Producteur(Stock stock,string nomproduit) { this.stock = stock; random = new Random(); this.nomproduit = nomproduit; public void run() { while (true) { Produit p = new Produit(nomProduit); try { Thread.sleep(random.nextInt(1000)+1000); catch(interruptedexception e) { stock.addproduit(p); System.out.println("Producteur "+getid()+" a rajoute "+p); 49

class Consommateur extends Thread { private Stock stock; private Random random; public Consommateur(Stock stock) { random = new Random(); this.stock = stock; public void run() { while (true) { try { Thread.sleep(random.nextInt(10000)+1000); catch(interruptedexception e) { Produit p = stock.removeproduit(); System.out.println("Consommateur "+getid() +" a enlevé "+p); 50

java.util.concurrent depuis la version 1.5, il existe trois packages très complets contenant des mécanismes de gestion de la concurrence java.util.concurrent qui contient (entre autres) des sémaphores, des futurs, des barrières, etc. java.util.concurrent.atomic qui contient diverses classes de nombres autorisant des opérations atomiques de modification java.util.concurrent.locks qui contient divers types de verrous 51