13.07.2015 Views

Synchronisation de threads en Java TP2 et TP3 : Pratique

Synchronisation de threads en Java TP2 et TP3 : Pratique

Synchronisation de threads en Java TP2 et TP3 : Pratique

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Synchronisation</strong> <strong>de</strong> <strong>threads</strong> <strong>en</strong> <strong>Java</strong><strong>TP2</strong> <strong>et</strong> <strong>TP3</strong> : <strong>Pratique</strong>V.Marangozova-Martin1 Moniteurs <strong>Java</strong>La synchronisation <strong>en</strong> <strong>Java</strong> est faite <strong>en</strong> utilisant les moniteurs. Dans le cours,nous avons vu qu’un moniteur est un obj<strong>et</strong> cont<strong>en</strong>ant <strong>de</strong>s variables <strong>et</strong> <strong>de</strong>s procéduresqui ne perm<strong>et</strong> qu’un processus actif à la fois. Ceci veut dire que siun processus exécute une procédure du moniteur, tous les autres processus quiveul<strong>en</strong>t exécuter <strong>de</strong>s procédures (la même ou d’autres), att<strong>en</strong><strong>de</strong>nt.En <strong>Java</strong>, un moniteur est attaché à un obj<strong>et</strong> <strong>et</strong> ce moniteur est activé à l’ai<strong>de</strong>du mot-clé synchronized.Dans le co<strong>de</strong> suivant :class Compte {private double s o l d e ;Compte ( double i ) { s o l d e = i ; }}synchronized void <strong>de</strong>poser ( double montant ) {s o l d e = s o l d e + montant ;}synchronized void r e t i r e r ( double montant ) {s o l d e = s o l d e − montant ;}double c o n s u l t e r ( ) {r<strong>et</strong>urn s o l d e ; }Ce co<strong>de</strong> spécifie que, quand un thread exécute la métho<strong>de</strong> <strong>de</strong>poser, aucunautre thread ne peut s’exécuter. En eff<strong>et</strong>, le thread acquiert le moniteur <strong>en</strong> début<strong>de</strong> métho<strong>de</strong> <strong>de</strong>poser <strong>et</strong> le relâche à la fin <strong>de</strong> la métho<strong>de</strong>.1


Miage3, 2009-2010 3Dans c<strong>et</strong> exemple, nous avons modifié le programme <strong>de</strong> manipulation <strong>de</strong>compte pour interdire le r<strong>et</strong>rait si il n’y a pas assez d’arg<strong>en</strong>t. Quand le sol<strong>de</strong> estinsuffisant, les <strong>threads</strong> ThreadR<strong>et</strong>irer att<strong>en</strong><strong>de</strong>nt (wait dans la métho<strong>de</strong> r<strong>et</strong>irer),ils sont réveillés par les <strong>threads</strong> ThreadDeposer qui appell<strong>en</strong>t la métho<strong>de</strong><strong>de</strong>poser cont<strong>en</strong>ant un appel à notify.Compiler <strong>et</strong> observer l’exécution <strong>de</strong> threadExemple6.Essayer <strong>de</strong> trouver un cas où un appel à r<strong>et</strong>irer est fait avec un sol<strong>de</strong> 0. Quese passe-t-il ?3.2 exempleThread7.javaCe programme est quasi i<strong>de</strong>ntique au programme précé<strong>de</strong>nt. La différ<strong>en</strong>c<strong>et</strong>i<strong>en</strong>t dans le fait que pour la vérification <strong>de</strong> la condition avant wait, nous avonsremplace le while par un if. Compiler <strong>et</strong> exécuter. Y a-t-il <strong>de</strong>s cas où le sol<strong>de</strong><strong>de</strong>vi<strong>en</strong>t négatif ? Faites au moins une dizaine d’exécution pour faire apparaîtrele problème. Expliquer.3.3 Le problème <strong>de</strong>s lecteurs-rédacteursIl s’agit d’accès concurr<strong>en</strong>ts à une ressource partagée par <strong>de</strong>ux types d’<strong>en</strong>tités: les lecteurs <strong>et</strong> les rédacteurs. Les lecteurs accè<strong>de</strong>nt à la ressource sansla modifier. Les rédacteurs, eux, modifi<strong>en</strong>t la ressource. Pour garantir un étatcohér<strong>en</strong>t <strong>de</strong> la ressource, plusieurs lecteurs peuv<strong>en</strong>t y accé<strong>de</strong>r <strong>en</strong> même tempsmais l’accès pour les rédacteurs est un accès exclusif. En d’autres termes, si unrédacteur travaille avec la ressource, aucune autre <strong>en</strong>tité (lecteur ou rédacteur)ne doit accé<strong>de</strong>r à celle-ci. Le problème <strong>de</strong>s lecteurs-rédacteurs est un problèmeclassique <strong>de</strong> synchronisation lors <strong>de</strong> l’utilisation d’une ressource partagée. Ceschéma est typiquem<strong>en</strong>t utilisé pour la manipulation <strong>de</strong> fichiers ou <strong>de</strong> zonesmémoire.Programmer les lecteurs rédacteurs. Notamm<strong>en</strong>t, écrire une première solutionqui définit une classe RessourcePartagée <strong>et</strong> <strong>de</strong>ux métho<strong>de</strong>s read <strong>et</strong> write<strong>en</strong> exclusion mutuelle (synchronized). Ces métho<strong>de</strong>s seront appelées par les<strong>threads</strong> lecteurs <strong>et</strong> rédacteurs. Avec c<strong>et</strong>te solution, est-il possible d’avoir <strong>de</strong>slectures <strong>en</strong> parallèle ?Ecrire une <strong>de</strong>uxième solution qui dispose <strong>de</strong> <strong>de</strong>ux compteurs : le nombre <strong>de</strong>lecteurs <strong>et</strong> le nombre <strong>de</strong> rédacteurs <strong>et</strong> qui utilise wait <strong>et</strong> notify.


Miage3, 2009-2010 44 RAPPELS : Threads <strong>en</strong> <strong>Java</strong>Les <strong>threads</strong> perm<strong>et</strong>t<strong>en</strong>t d’avoir plusieurs activités <strong>en</strong> parallèle dans un programme.Les <strong>threads</strong> <strong>Java</strong> peuv<strong>en</strong>t être implém<strong>en</strong>tés <strong>de</strong> <strong>de</strong>ux manières.Utilisation <strong>de</strong> la classe Thread La première métho<strong>de</strong> est d’ét<strong>en</strong>dre laclasse prédéfinie Thread :// classes <strong>et</strong> interfaces pre<strong>de</strong>finies <strong>Java</strong> , JDKinterface Runnable {void run ();}public class Thread ext<strong>en</strong>ds Objectimplem<strong>en</strong>ts Runnable {void run () {...}void start () {...}...}public class Compteur ext<strong>en</strong>ds Thread {public void run () {...}}public static main () {Compteur c = new Compteur ();c. start ();}}L’héritage à partir <strong>de</strong> Thread est contraignant car il empêche tout autrehéritage (<strong>en</strong> <strong>Java</strong>, une classe ne peut hériter qu’une seule autre classe).Utilisation <strong>de</strong> l’interface Runnable La <strong>de</strong>uxième manière <strong>de</strong> faire estd’implém<strong>en</strong>ter l’interface Runnable. Ceci perm<strong>et</strong> l’héritage d’autres classes <strong>et</strong><strong>et</strong> l’implém<strong>en</strong>tation d’autres interfaces.interface Runnable {void run ();}public class Thread ext<strong>en</strong>ds Objectimplem<strong>en</strong>ts Runnable {void run () {...}void start () {...}...}public class Compteur implem<strong>en</strong>ts Runnable{public void run () {...}}public static main () {


Miage3, 2009-2010 5}}Compteur c = new Compteur ();new Thread(c). start (); }

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!