next up previous contents index
Next: La Machine Virtuelle Java Up: Objets Previous: La fonction main

    
Flots d'instructions : les threads

La programmation à objets provient du besoin d'exprimer des interactions. Jusqu'à présent, deux objets peuvent interagir quand l'un invoque une méthode de l'autre objet : cette forme d'interaction est ainsi limitée à la réponse d'un objet à un autre objet. Un agent  est un objet doté d'un comportement qui lui permet d'agir sans qu'il soit sollicité par d'autres objets. Jusqu'à présent, seule la fonction main() de la classe principale a cette capacité, mais, étant statique, elle n'est pas associée à un objet. La fonction main() définit le flot d'instructions exécutées par le programme. L'idée est de créer des agents, ayant chacun son propre flot d'instructions.

Un flot d'instructions est modélisé en Java par un thread, ou unité séquentielle d'exécution (ou encore brin, traduction littérale de thread, ou processus léger). Quand une application est démarrée, l'environnement Java crée un thread principal exécutant la fonction main() de l'application. D'autres threads peuvent être créés, soit par l'environnement d'exécution, soit par le programme. Chacun de ces threads exécute une fonction, en concurrence avec les autres ; ils communiquent entre eux via des objets partagés. C'est de la programmation multithread.

Un thread est créé par instanciation de la classe Thread, ou d'une classe dérivée de Thread. La classe Thread définit une méthode run() qui ne fait rien. C'est en redéfinissant cette méthode dans une classe dérivée que l'on donne un comportement à un objet :

   

class T extends Thread {
    
  public void run() { ... }
    
}
    
 ... new T().start(); ...
Un thread, une fois créé, est dans son état initial. La méthode start(), qui retourne immédiatement, le fait passer dans l'état actif, dans lequel il peut être effectivement exécuté (sur un monoprocesseur, il sera exécuté en temps partagé avec les autres unités). Il faut noter que la méthode run() n'est jamais appelée explicitement dans le programme (exactement de la même façon que la méthode main() d'une application). L'exécution d'un thread peut être suspendue de différentes façons, puis reprise. Le thread passe dans l'état terminé quand run() termine. L'exemple suivant montre deux agents, l'un émettant un 'a', l'autre un 'b' à des instants aléatoires :

class Concurrence {
  public static void main(String[] args) {
    Agent 
      a = new Agent('a'), 
      b = new Agent('b');
    a.start();
    b.start();
  }
}

Chaque agent est une instance de la classe suivante, qui redéfinit la méthode run() de Thread (cette méthode doit recourir au mécanisme de traitement d'exception, try ... catch, qui sera expliqué au § 3.21) :

class Agent extends Thread {
  char c;
  Agent(char c) {
    this.c = c;
  }
  
public void run() {
    while(true) {
      System.out.print(c);
      try {
        Thread.sleep((long)(Math.random()*1000));
      } catch (InterruptedException e) {}
    }
  }
}

L'exécution de ce programme affiche une suite de caractères, résultat de l'entrelacement des comportements de chaque agent :

baabababbabbaaababbabbbbaabbabaaababbabababaa ...

La programmation multithread est un aspect important de la programmation des systèmes logiciels contemporains.


next up previous contents index
Next: La Machine Virtuelle Java Up: Objets Previous: La fonction main
R. Lalement
2000-10-23