Synchro et Threads Java TM NICOD JEAN-MARC Master 2 Informatique Université de Franche-Comté UFR des Sciences et Techniques septembre 2008 NICOD JEAN-MARC Synchro et Threads avec Java TM 1 / 32
Sommaire Introduction 1 Introduction 2 3 4 NICOD JEAN-MARC Synchro et Threads avec Java TM 2 / 32
Sommaire Introduction Généralités Création d une activité Méthodes de la classe Thread 1 Introduction Généralités Création d une activité Méthodes de la classe Thread 2 3 4 NICOD JEAN-MARC Synchro et Threads avec Java TM 3 / 32
Généralités Introduction Généralités Création d une activité Méthodes de la classe Thread Applications concurrentes Traitements parallèles Gestions des communications : attente active vs attente passive Partage de ressources communes Gestion de problèmes de synchronisation et d exlusion mutuelle. NICOD JEAN-MARC Synchro et Threads avec Java TM 4 / 32
Processus vs Threads Généralités Création d une activité Méthodes de la classe Thread Processus : gestion système, espace mémoire propre (même avec les proc fils), temps partagé avec les autres processus, ordonnancement garanti (priorités) Threads : gestion logicielle ou système espace mémoire partagé, temps partagé dans le processus, transparent pour les autres applications du processeur, ordonnancement non garanti (les priorités ne sont pas toujours gérées) attention : partage = manipulation de la synchrosisation NICOD JEAN-MARC Synchro et Threads avec Java TM 5 / 32
Les Threads Java Introduction Généralités Création d une activité Méthodes de la classe Thread Lancement de la machine virtuelle Java Lancement dynamique des threads Méthodes de manipulation des threads : terminé fin du code exécutable actif (sur le CPU) read accept bloqué (E/S) créé start yield exécutable pret notify interrupt wait, join, sleep bloqué (synchro ou sleep) NICOD JEAN-MARC Synchro et Threads avec Java TM 6 / 32
Création d une activité (thread) Généralités Création d une activité Méthodes de la classe Thread Existance de la classe java.lang héritage de la classe Thread implémentation de l interface Runnable si héritage multiple NICOD JEAN-MARC Synchro et Threads avec Java TM 7 / 32
Héritage de la classe Thread Généralités Création d une activité Méthodes de la classe Thread Écriture (surchage) de l invocation de la méthode run() : méthode appelée lors de l invocation de la méthode start() sur un objet de la classe Thread exemple : class MonThread extends Thread {... public void run() {... code de l activité... class Principale { public static void main(string[] argv) { MonThread p = new MonThread(...); p.start();... NICOD JEAN-MARC Synchro et Threads avec Java TM 9 / 32
Héritage de la classe Thread Généralités Création d une activité Méthodes de la classe Thread Implémentation de l interface Runnable écriture de la méthode run() exemple : class MonThread implements Runnable {... public void run() {... code de l activité... class Principale { public static void main(string[] argv) { MonThread p = new MonThread(...); Thread t = new Thread(p); t.start();... NICOD JEAN-MARC Synchro et Threads avec Java TM 11 / 32
Généralités Création d une activité Méthodes de la classe Thread Quelques méthodes de la classe Thread Constructeurs : Thread(ThreadGroup, Runnable, String) nom du thread par défaut : Thread-+<entier> static Thread currentthread() ref sur le thread courant static void yield() passe la main static void sleep(long ms) throws InterruptedException NICOD JEAN-MARC Synchro et Threads avec Java TM 12 / 32
Vie des threads Introduction Généralités Création d une activité Méthodes de la classe Thread void start() positionne le thread en configuration prêt void join() throws InterruptedException attend la fin d exécution du thread courant void join(long ms) throws InterruptedException attend la fin ou le temps du time out boolean isalive() : prêt, bloqué ou en exécution NICOD JEAN-MARC Synchro et Threads avec Java TM 13 / 32
Interruption Introduction Généralités Création d une activité Méthodes de la classe Thread Il est possible d interrompre des threads : méthode interrupt sur le thread appelant (la méthode) 1 thread bloqué sur wait(), join(), sleep() : exception InterruptedException 2 positionnement d un indicateur isinterrupted interrogé avec : boolean isinterrupted() renvoie la valeur de l indicateur du thread appelant ; static boolean interrupted() renvoie et efface la valeur de l indicateur du thread appelant. NICOD JEAN-MARC Synchro et Threads avec Java TM 14 / 32
Différence entre thread et objet Généralités Création d une activité Méthodes de la classe Thread class MesThreads extends Thread { public void nomthreadcourant () { System.out.println( Thread.currentThread().getName() ) ; public void run () { this.nomthreadcourant () ; class TesThreads extends Thread { MesThreads mt ; TesThreads ( MesThreads mt ) { this.mt = mt ; public void run() { mt.nomthreadcourant () ; résultat de l exécution public class DonneMoiTonNom { public static void main (String args[]){ MesThreads mt = new MesThreads () ; TesThreads tt = new TesThreads ( mt ) ; mt.setname ("MonThread") ; tt.setname ("TonThread") ; mt.start () ; tt.start () ; mt.nomthreadcourant () ; MonThread TonThread main NICOD JEAN-MARC Synchro et Threads avec Java TM 16 / 32
Sommaire Introduction Partage de l espace d adressage Protection de l accès à la mémoire 1 Introduction 2 Partage de l espace d adressage Protection de l accès à la mémoire 3 4 NICOD JEAN-MARC Synchro et Threads avec Java TM 17 / 32
Partage de l espace d adressage Partage de l espace d adressage Protection de l accès à la mémoire Les threads issus d un même espace d adressage partage le même espace d adressage ( fork()). Les variables partagées sont : variables de classe partagées par toutes les instances de la classe (static) ou passé en paramètre du constructeur. exercice : Soit une classe gérant les sommes créditées sur un compte commun. Écrire le programme formé d un programme principal et de 2 acteurs apportant respectivement 1500AC et 1000AC. À la suite de tout ajout, le solde du compte est affiché par les acteurs. À la fin de l exécution des acteurs, le solde du compte commun est affiché par le programme principal. NICOD JEAN-MARC Synchro et Threads avec Java TM 18 / 32
Partage de l espace d adressage Protection de l accès à la mémoire Exemple 1 : crédit sur un compte commun une solution : class PartageMemoire extends Thread { private static int cptecommun = 0; private int salaire; PartageMemoire ( int monsalaire ) { salaire = monsalaire; public void run() { cptecommun = cptecommun + salaire; System.out.println( "Cpte Commun " + cptecommun + " euros" ); public static void main(string args[]) { Thread t1 = new PartageMemoire ( 1500 ); Thread t2 = new PartageMemoire ( 1000 ); t1.start(); t2.start(); try { t1.join(); t2.join(); catch (InterruptedException e){ System.out.println( "Cpte Commun final " + cptecommun + " euros" ); résultat de l exécution Compte Commun... 1500 euros Compte Commun... 2500 euros Compte Commun final... 2500 euros NICOD JEAN-MARC Synchro et Threads avec Java TM 20 / 32
Problème de concurrence d accès Partage de l espace d adressage Protection de l accès à la mémoire Importance de protéger la mémoire en lecture/écriture : class MyAddress { String n ; String add ; class StoreData Thread { static MyAddress c ; String myname ; String myadd ; private int me; StoreData (String n, String a, int me) { myname = n ; myadd = a ; this.moi = moi; public void run() { c.n = myname ; if (me == 1) try { this.sleep(10); catch (InterruptedException e){; c.add = new String (myadd) ; System.out.println( "Data from " + me + " : " + c.n + " " + c.add ); public static void main(string args[]) { Thread t1 = new StoreData("BOB","LILLE",1); Thread t2 = new StoreData("SAM","NICE",2); c = new MyAddress () ; t1.start(); t2.start(); try { t1.join(); t2.join(); catch (InterruptedException e){ System.out.println( "Stored data : " + c.n + " " + c.add ); résultat de l exécution : Data from 2 : SAM NICE Data from 1 : SAM LILLE Stored Data : SAM LILLE NICOD JEAN-MARC Synchro et Threads avec Java TM 22 / 32
Sommaire Introduction Exclusion mutuelle Barrière de synchronisation (rdv) 1 Introduction 2 3 Exclusion mutuelle Barrière de synchronisation (rdv) 4 NICOD JEAN-MARC Synchro et Threads avec Java TM 23 / 32
Exclusion mutuelle Barrière de synchronisation (rdv) Importance des outils de Synchronisation concurrence d accès à des ressources communes concurrence d accès à des données partagées exclusion mutuelle exécution concurrente barrière de synchronisation ou gestion des rendez-vous NICOD JEAN-MARC Synchro et Threads avec Java TM 24 / 32
Exclusion mutuelle Barrière de synchronisation (rdv) Importance des outils de Synchronisation concurrence d accès à des ressources communes concurrence d accès à des données partagées exclusion mutuelle exécution concurrente barrière de synchronisation ou gestion des rendez-vous NICOD JEAN-MARC Synchro et Threads avec Java TM 24 / 32
Gestion de l exclusion mutuelle Exclusion mutuelle Barrière de synchronisation (rdv) classiquement gérée par des mutex en Java : protection de l accès à une donnée, un objet, une portion de code ou une méthode par le mot clé synchronized (prise d un verrou) : 1 un objet : synchronized (monobjet) {... section critique... 2 une ou plusieurs méthodes d un objet : synchronized TypeRetour1 mamethode1 (... ) {... synchronized TypeRetour2 mamethode2 (... ) {... 3 une ou plusieurs méthodes d une classe : class MesObjets { static synchronized TypeRetour1 mamethode1 (... ) {... static synchronized TypeRetour2 mamethode2 (... ) {... NICOD JEAN-MARC Synchro et Threads avec Java TM 26 / 32
Gestion de l exclusion mutuelle Exclusion mutuelle Barrière de synchronisation (rdv) classiquement gérée par des mutex en Java : protection de l accès à une donnée, un objet, une portion de code ou une méthode par le mot clé synchronized (prise d un verrou) : 1 un objet : synchronized (monobjet) {... section critique... 2 une ou plusieurs méthodes d un objet : synchronized TypeRetour1 mamethode1 (... ) {... synchronized TypeRetour2 mamethode2 (... ) {... 3 une ou plusieurs méthodes d une classe : class MesObjets { static synchronized TypeRetour1 mamethode1 (... ) {... static synchronized TypeRetour2 mamethode2 (... ) {... NICOD JEAN-MARC Synchro et Threads avec Java TM 26 / 32
Gestion de l exclusion mutuelle Exclusion mutuelle Barrière de synchronisation (rdv) classiquement gérée par des mutex en Java : protection de l accès à une donnée, un objet, une portion de code ou une méthode par le mot clé synchronized (prise d un verrou) : 1 un objet : synchronized (monobjet) {... section critique... 2 une ou plusieurs méthodes d un objet : synchronized TypeRetour1 mamethode1 (... ) {... synchronized TypeRetour2 mamethode2 (... ) {... 3 une ou plusieurs méthodes d une classe : class MesObjets { static synchronized TypeRetour1 mamethode1 (... ) {... static synchronized TypeRetour2 mamethode2 (... ) {... NICOD JEAN-MARC Synchro et Threads avec Java TM 26 / 32
Exclusion mutuelle Barrière de synchronisation (rdv) Correction de la classe StoreData protection la section critique avec synchronized : class MyAddress { String n ; String add ; class StoreData Thread { static MyAddress c ; String myname ; String myadd ; private int me; StoreData (String n, String a, int me) { myname = n ; myadd = a ; this.moi = moi; public void run() { synchronized ( c ) { c.n = myname ; if (me == 1) try { this.sleep(10); catch (InterruptedException e){; c.add = new String (myadd) ; System.out.println( "Data from " + me + " : " + c.n + " " + c.add ); public static void main(string args[]) { Thread t1 = new StoreData("BOB","LILLE",1); Thread t2 = new StoreData("SAM","NICE",2); c = new MyAddress () ; t1.start(); t2.start(); try { t1.join(); t2.join(); catch (InterruptedException e){ System.out.println( "Stored data : " + c.n + " " + c.add ); résultat de l exécution : Data from 1 : BOB LILLE Data from 2 : SAM NICE Stored Data : SAM NICE NICOD JEAN-MARC Synchro et Threads avec Java TM 28 / 32
Exclusion mutuelle Barrière de synchronisation (rdv) Barrière de synchronisation ou rendez-vous Gestion des verrous à la main à l aide des mots clé : unobjet.wait() lève le verrou sur l objet et bloque le thread appelant jusqu à ce qu une méthode notify() ou notifyall() ne le réveille. Une interruption ou un time out peut aussi conduire au déblocage du thread. Une fois débloqué, il est mis en attente pour l accès exclusif à la section critique. Il passe donc en mode prêt. unobjet.notify() réveille un thread alors bloqué par un wait(). Si aucun thread n est bloqué, rien ne se passe. Le thread débloqué doit alors prendre le verrou dès qu il le pourra. unobjet.notifyall() réveille tous les threads bloqués par un wait(). C est le thread qui prend le premier le verrou qui accède à la section critique. NICOD JEAN-MARC Synchro et Threads avec Java TM 29 / 32
Exclusion mutuelle Barrière de synchronisation (rdv) Exemple d utilisation de wait() et notify() Écriture des sémaphores inexistant en Java Résolution des problèmes classiques de synchronisation producteurs/consommateurs, lecteur/rédacteur, diner des philosophes,... NICOD JEAN-MARC Synchro et Threads avec Java TM 30 / 32
Mise en garde Introduction Exclusion mutuelle Barrière de synchronisation (rdv) attention à la non garantie d accès des threads au processeur Quelle conséquence pour les problèmes de synchronisation, barrière de synchronisation, traitements autour de la section critique? NICOD JEAN-MARC Synchro et Threads avec Java TM 31 / 32
Sommaire Introduction 1 Introduction 2 3 4 NICOD JEAN-MARC Synchro et Threads avec Java TM 32 / 32