0% ont trouvé ce document utile (0 vote)
22 vues23 pages

Chap4 MultiThreadsJava

Ce document présente une introduction à la programmation concurrente en Java, en expliquant les concepts de threads et de multi-threading. Il décrit deux méthodes pour créer des threads : en dérivant la classe Thread ou en implémentant l'interface Runnable, ainsi que les mécanismes de synchronisation pour gérer l'exclusion mutuelle. Enfin, il aborde le framework Executor introduit dans Java 5 pour optimiser la gestion des threads.

Transféré par

FA Tima
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
22 vues23 pages

Chap4 MultiThreadsJava

Ce document présente une introduction à la programmation concurrente en Java, en expliquant les concepts de threads et de multi-threading. Il décrit deux méthodes pour créer des threads : en dérivant la classe Thread ou en implémentant l'interface Runnable, ainsi que les mécanismes de synchronisation pour gérer l'exclusion mutuelle. Enfin, il aborde le framework Executor introduit dans Java 5 pour optimiser la gestion des threads.

Transféré par

FA Tima
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Chap : Introduction à la programmation concurrente

en Java

Thread : séquence autonome d’exécution d’instructions au sein
d’un programme

Le multi-threading donne l’illusion de parallélisme de
l’exécution des bouts de programmes


Délivre un parallélisme réel sur une machine multiprocesseur
Pour créer des Threads…

Deux façons :

Façon 1 : Dériver une classe de la classe Thread.

Façon 2 : implémenter l’interface Runnable.

Un point commun : écrire une méthode run() qui fait


ce que doit faire le thread.
1ère façon

Etape 1 : Définir une classe fille de Thread et définition de la


méthode run()
public class MonThread extends Thread {
public void run() {
...
}
}
Etape 2 : Instancier un objet de la classe MonThread et lancer la
méthode prédéfinie start() prédéfinie

MonThread theThread = new MonThread ();


[Link]();

Rq : si on fait [Link]() alors run


s'exécute sans créer un nouveau thread
1ère façon

public class MonThread extends Thread {


public void run() {
for ( int i1=1; i1<100; i1++)
[Link](">>> i1 = "+i1);
}
}

class Test {
public static void main(String[] x) {
MonThread theThread = new MonThread ();
[Link]();
for ( int i2 =1; i2<100;i2++)
[Link](" i2 = "+i2);
}
1ère façon : une autre écriture

public class MonThread extends Thread {


MonThread {
[Link]() ;
}
public void run() {
for ( int i1=1; i1<100; i1++)
[Link](">>> i1 = "+i1);
}
}

new MonThread();
Façon 2

Etape_1 : définir une classe qui implémente l'interface Runnable, et


définition de la méthode run()

public class MonThread implements Runnable {


public void run() {

}
}
Etape_2 : créer un objet de cette classe
MonThread T = new MonThread( );

Etape_3 : créer un objet de la classe Thread prédéfinie de la façon


suivante :
Thread theThread = new Thread (T) ;

Etape_4 : Appeler la méthode start()


[Link]() ;
2ème façon (une autre écriture utilisant la classe
Runnable)

Runnable job = new Runnable() {


public void run() {
...
}
};

Thread t1 = new Thread(job, "Premier thread");


[Link]();

Thread t2 = new Thread(job, "Second thread");


[Link]();

Pourquoi on offre deux façons de définir les threads ?


Exercice : Écrire un programme qui créer cinq Threads
identiques
Mise en place de l'exclusion mutuelle
Deux mécanismes:
● Un mécanisme de synchronisation léger en utilisant le mot clé
volatile:

Int volatile x ;

si un thread_a change la valeur de x alors on a une garantie que toute


autre thread_b utilisant x trouvera la bonne valeur.

● Un mécanisme plus complet utilisant le mot clé synchronized.

● Sachant qu'a chaque objet Java est associé automatiquement un


(et un seul) verrou, appelé aussi moniteur de l'objet.
La directive synchronized

● On a le choix de faire l'exclusion mutuelle soit à une méthode en


totalité :

type_x synchronized methode_x () {…}

● Soit un bloc d'instructions :

i++ ; synchronized (this) {…} ; j++


ou
i++ ; synchronized (objet_a) {….} ; j++

C'est le verrou de l'objet courant qui est pris par le thread


courant.

Si un 2ème thread tente de prendre le verrou alors il se bloque.


La directive synchronized

Le verrou d'un objet O est libéré :


- soit à la fin du bloc synchronized() {...}
- soit à l'appel de la méthode [Link]() par le thread possédant le
verrou.
public class SavingsAccount
{
private float balance;

public synchronized void withdraw(float anAmount)


{
if ((anAmount>0.0) && (anAmount<=balance))
balance = balance ­ anAmount;
}

public synchronized void deposit(float anAmount)


{
if (anAmount>0.0)
balance = balance + anAmount;
}
public class SavingsAccount
{
private float balance;

public void withdraw(float anAmount)


{
if (anAmount<0.0)
throw new IllegalArgumentException("Withdraw
amount negative");
synchronized(this)
{
if (anAmount<=balance)
balance = balance ­ anAmount;
}
}

public void deposit(float anAmount)


{
La synchronisation coopérative avec les
méthodes wait() et notify()

● Wait() fait suspendre le thread courant jusqu'à ce que un autre


thread fait notify()
● Ceux sont des méthodes de la classe Object
● Ces méthodes doivent être appélées qu'à l'intérieur d”un bloc
synchronized {…}
wait()

● Trois syntaxes d'appels différentes:


wait(), [Link]() ou objet_x.wait()

● Dans les trois cas le thread appelant passe à l'état wait.


Mais pour des raisons différentes:
objet_x.wait(): Attente d'un signal de l' objet_x
[Link](): Attente d'un signal de l'objet courant
wait(): Attente d'un signal de cet objet thread (c.à d. du thread
courant)

● Le monitor de l'objet marque que ce thread appelant est en


attente d'un signal de cet objet.
wait()

● Le thread appelant objet_x.wait() doit être en


possession du verrou de objet_x:
synchronized (objet_x) {

objet_x.wait();

● Après l'appel à objet_x.wait() ce verrou est libéré ( afin


que le thread ne garde pas le verrou)
notify()

Trois syntaxes d'appels différentes:


notify(), [Link]() ou objet_x.notify()

● A l'appel de objet_x.notify() par un thread_b, le VJM


débloque l'un des threads en attente d'un signal de objet_x.
Mais le thread débloqué doit récupérer le verrou avant de
progresser
● objet_x.notifyAll() débloquent tous les thread_b en
attente d'un signal de objet_x
Les états d'un thread Java
Attributs et méthodes de la classe
Thread

public class Thread implements Runnable {

public static final int MAX_PRIORITY, MIN


_PRIORITY, NORM _PRIORITY;
public Thread();
public Thread(String name);

public static Thread currentThread();
public static void sleep(long millis);


}
Attributs et méthodes de la classe
Thread

public class Thread implements Runnable {


...
public static void suspend();
public static void resume();

public static void start();
public static void stop();
public static void run();
public static void wait(); //arrête le
thread en attendant une notification
public static void notify(); // notification
des threads en attentes par wait

}
Le framework Executor ( à partir de Java 5)

Pb : si une application a à créer en tout et pour


tout M threads sachant qu'au maximum N
threads coexisteront au même temps, alors si
M>>N trop de temps serait perdu dans la création
des threads.

Solution : Utilisation d'un pool de threads


([Link]).
Le framework Executor (Java 5)

import [Link] ;

Runnable job = new Runnable() {


public void run() {
...

}
};

// Pool de 4 threads
ExecutorService pool = [Link](4);
[Link](job);
[Link](job);

Voir Demo...

Vous aimerez peut-être aussi