Threads§

Introduction aux threads§

Qu'est-ce que c'est ?§

Comment créer un thread ?§

Première façon de faire: dériver java.lang.Thread.

public classe MonPremierThread extends Thread {
  public void run() { ... }
}

L'appel à la méthode start (héritée) lance l'exécution de la méthode run. L'exécution du thread se termine au retour de la méthode run.

MonPremierThread t = new MonPremierThread();
monPremierThread.start();

Comment éviter l'héritage ?§

L'héritage de java.lang.Thread est contraignant car il empêche tout autre héritage. Il existe une seconde façon de faire: implémenter l'interface java.lang.Runnable.

public classe MaClasseRunnable implements Runnable {
  public void run() { ... }
}

On passe une instance de la classe implémentant Runnable au constructeur de Thread.

MaClasseRunnable r = new MaClasseRunnable();
Thread t = new Thread( r );
t.start();

Méthodes de la classe Thread§

Synchronisation physique§

Etats d'un thread§

Un thread peut être:

Les threads utilisant la même ressource partagée doivent être synchronisés.

Partage de la mémoire§

Chaque instance de Thread, chaque instance d'une classe Runnable possède ses propres champs. Pour partager une donnée entre plusieurs threads:

Ex.1. Compteur (10 min)§

private synchronized void toNextEven() {

Ex.2. Tableaux de threads (10 min)§

Piscine piscine = new Piscine();    //la piscine
int n = 150;
Thread[] baigneurs = new Thread[n];
for (int i = 0; i < n; i++)         //les baigneurs
    baigneurs[i] = new Thread( new Baigneur(piscine, 5) );

Ex.3. Accès concurrents (10 min)§

synchronized (this) {
   ...
}

L'objet entre parenthèse est utilisé de manière exclusive par le thread courant. L'exécution des autres threads est bloquée jusqu'à ce que le thread courant exécute la dernière instruction du bloc.

Ce qu'il faut retenir§

Quand plusieurs threads partagent des données, il peut y avoir interférence (deux exécutions d'une même méthode sont entrelacées) ou incohérence (les appels de différentes méthodes d'un même objet sont entrelacés).

Pour éviter ces problèmes, on peut définir des sections critiques avec le mot-clef synchronized.

Dans les deux cas, la synchronisation porte sur un objet particulier.

Synchronisation temporelle§

Méthodes§

Problème producteur/consommateur§

Ex.4. Wait/Notify (20 min)§

Ce qu'il faut retenir§

Pour aller plus loin§

Fabrique de threads§

Le package java.util.concurrent contient une classe Executors fabriquant:

Ces méthodes renvoient en fait un objet de type ExecutorService, sous-type de Executor. Autrement dit, un objet issu d'une classe implémentant l'interface ExecutorService, dérivant l'interface Executor.

Executor§

Les objets de type Executor possèdent une méthode execute() qui crée, puis démarre un thread.

Si e est un objet de type Executor et si r est un objet de type Runnable, alors ces codes sont équivalents:

Thread t = new Thread(r);
t.start();
e.execute(r);

A la maison. Pool de threads (10 min)§