COURS
THREADING
LA SYNCHRONISATION
1
2
PROBL ME DE
SYNCHRONISATION
Exemple :
class Echangeur
{
int a, b;
Echangeur (int a, int b)
{
this.a = a;
this.b = b;
}
void echange ( )
{
int sauv;
sauv = a;
a = b;
b = sauv;
}
}
class MonThread extends Thread
{
Echangeur e;
MonThread (Echangeur e)
{
this.e = e;
}
public void run ( )
{
e.echange ();
}
}
3
PROBL ME DE
SYNCHRONISATION (SUITE)
public class TestEchangeur
{
public static void main (String[ ] args) {
Echangeur e = new Echangeur ( 3, 2);
MonThread th1 = new MonThread (e);
MonThread th2 = new MonThread (e);
th1.start ( );
th2.start ( );
try
{
th1.join();
th2.join();
}
catch (Exception ee) { }
System.out.println("a = "+e.a+" , b = "+e.b);
}
}
R sultat attendu :
2 changes successifs a = 3, b = 2
R sultats possibles :
a = 2, b = 3 (1 instruction / instruction)
a = 2, b = 2 (2 instructions / 2 instructions)
a = 3, b = 3 (1 instructions / 3 instructions )
a = 3, b = 2 (3 instructions / 3 instructions)
&
Advertisement
4
SOLUTION : LA
SYNCHRONISATION
La programmation par threads impose souvent de
disposer de m canismes permettant de contr ler les
concurrences dacc s des donn es partag es
En Java, ce probl me sappuie sur le concept de
moniteur (ou verrou ): Un verrou est associ
un objet selon deux m canismes :
1.
D finir une m thode comme tant synchronized, le
verrou est plac sur lobjet sur lequel est appel la
m thode
(Lorsquun thread d roule cette m thode sur un
objet, un autre thread ne peut pas lex cuter pour le
m me objet, la m thode est disponible pour un seul
thread la fois)
Restreindre lutilisation dun objet pour un thread
la fois par synchronized (objet) { & }
(Lacc s lobjet en param tre est r serv un
thread et un seul jusqu la fin du bloc synchronis )
Remarques:
1.
Un objet verrouill peut tre modifi par un code
non synchronis
Quand le code synchronis a fini par sex cuter le
verrou sur lobjet sera rel ch
2.
2.
5
EXEMPLE
1. Synchronisation la source
class Echangeur
{
int a, b;
Echangeur (int a, int b)
this.a = a;
{
this.b = b;
}
synchronized void echange ( )
{
int sauv;
sauv = a;
a = b;
b = sauv;
}
}
Ou
2. Synchronisation l utilisation
class MonThread extends Thread
{
Echangeur e;
MonThread (Echangeur e)
{
this.e = e;
}
public void run ( )
{
synchronized (e)
{
e.echange ( );
}
}
Advertisement
}
6
LES M THODES WAIT( ) ET
NOTIFY( )
Object.wait ( ) :
Ne peut tre utilis e que dans un code
synchronis
Elle provoque lattente du thread en cours
dex cution
Elle doit tre appel e sur lobjet verrouill
Pendant lattente du thread, le verrou sur
lobjet est rel ch
On peut avoir :
synchronized (objet)
{ // objet bloque le thread en cours dex cution
objet.wait ( );}
Ou
synchronized methode ( )
{// blocage du thread en cours dex cution
wait ( );
}
void wait (long temps )
temps millisecondes
: termine lattente apr s
LES M THODES WAIT( ) ET
NOTIFY( )
Object.notify ( ) :
Permet de d bloquer un thread (bloqu par
wait( ))
On peut avoir :
synchronized (objet)
{ objet.notify( );} // d bloque le thread bloqu par ce
m me objet
Ou
synchronized methode ( )
{ notify ( ); }
void notifyAll ( )
threads bloqu s
: permet de d bloquer tous les
7
8
UN PROBL ME DE TYPE
PRODUCTEUR-CONSOMMATEUR
Producteur
Consommateur
Principe :
Buffer
"
"
"
Le Producteur empile des donn es dans le Buffer
Le Consommateur demande au Buffer de lui donner une
information
Lorsquune information est disponible, le Consommateur la prend
Impl mentation :
"
"
"
"
Le producteur et le consommateur sont deux threads qui
sex cutent en parall le
Ils poss dent chacun son propre rythme de production ou de
consommation
Si le buffer est vide le consommateur attend jusqu ce que le
Advertisement
producteur y d pose quelque chose
Si le buffer est plein le producteur attend jusqu ce que le
consommateur lib re de la place
9
PROGRAMME
class Producteur extends Thread {
private Buffer buffer;
private String donnee;
Producteur (Buffer buffer, String donnee) {
this.buffer = buffer;
this.donnee = donnee;}
public void run ( ) {
for (int i = 0; i < donnee.length( ); i++)
{
char car =donnee.charAt(i);
buffer.poser (car);
System.out.println ( jai produit : +car);
try {sleep ((int)(Math.random()*10));}
catch (InterruptedException e){}
}
System.out.println (" \nProduction termin e"); }}
class Consommateur extends Thread {
private Buffer buffer;
private int nb;
Consommateur (Buffer buffer, int nb) {
this.buffer = buffer;
this.nb = nb; }
public void run ( ) {
for (int i = 0; i < nb; i++)
{
char car = buffer.prendre();
System.out.println ( jai consomm : + car);
try {sleep ((int)(Math.random()*1000));}
catch (InterruptedException e) {}
}
System.out.println ("\nConsommation termin e"); } }
1
0
PROGRAMME (SUITE)
class Buffer extends Pile
{
Buffer (int taille) {
super (taille);
}
public synchronized void poser (char c)
{
if (pilePleine( ))
{
try {wait ( );}
catch (InterruptedException e) {}
}
empiler (c);
notify ( );
}
public synchronized char prendre ( )
{
if (pileVide( ))
{
try {wait ( );}
catch (InterruptedException e) {}
}
char c = depiler();
notify ( );
return (c);
Advertisement
}
}
1
1
PROGRAMME (SUITE)
class Pile {
private char [ ] tab ;
private int nbElem ;
Pile (int n) {
// Allocation du tableau de dimension n
tab = new char ; }
void empiler (char e) {
tab = e;
nbElem++;
}
char depiler ( ) {
nbElem--;
return (tab ); }
boolean pilePleine ( ) {
if (nbElem == tab.length) return (true);
else
return (false); }
boolean pileVide ( )
{
if (nbElem == 0) return (true);
return (false); } }
else
public class Test {
public static void main (String[ ] args) {
String donnee = 123456789 ;
Buffer buffer = new Buffer (4 );
Producteur p = new Producteur (buffer, donnee);
Consommateur c = new Consommateur(buffer,
donnee.length( ));
p.start( );
c.start( );
}}
1
2
PROGRAMME (SUITE)
R sultat :
Jai produit : 1
Jai consomm : 1
Jai produit : 2
Jai produit : 3
Jai produit : 4
Jai produit : 5
Jai consomm : 5
Jai produit : 6
Jai consomm : 6
Jai produit : 7
Jai consomm : 7
Jai produit : 8
Jai consomm : 8
Jai produit : 9
Production termin e
Jai consomm : 9
Jai consomm : 4
Jai consomm : 3
Jai consomm : 2
Consommation termin e