Créer un thread

Il existe deux façons de créer un thread : par dérivation de la classe Thread et par implémentation de l'interface Runnable.

1- Par dérivation de la classe Thread

Dans cette première approche, on crée d'abord une classe dérivée de Thread et on redéfinit sa méthode run. Cette dernière contiendra le code éventuellement exécuté dans un thread.

class MonThread extends Thread {
    @Override
    public void run() {
        // code exécuté par le thread
    }
}

On crée ensuite une instance de cette classe et on appelle la méthode start (héritée de la classe Thread) qui lance l'exécution de la méthode run dans un nouveau thread.

// création du thread
Thread t = new MonThread(); // ou MonThread t = new MonThread();

// lancement (exécution de la méthode run)
t.start();

2- Par implémentation de l'interface Runnable

Dans cette seconde approche, on crée d'abord une classe qui implémente l'interface Runnable et on redéfinit sa méthode run. Cette dernière contiendra le code éventuellement exécuté dans un thread.

class MonRunnable implements Runnable {
    // une classe qui implémente l'interface Runnable doit obligatoirement
    // redéfinir la méthode run
    @Override
    public void run() {
        // code exécuté par le thread
    }
}

On crée ensuite une instance de cette classe, mais puisque cette dernière n'est pas un thread (ne dérive pas de Thread), il faut quand même créer une instance de la classe Thread.

Lors de la création du thread, l'objet qui implémente l'interface Runnable est passé en paramètre au constructeur. On peut ensuite appeler la méthode start du thread pour lancer l'exécution de la méthode run de l'objet Runnable.

// création d'un objet qui implémente Runnable
Runnable runner = new MonRunnable(); // ou MonRunnable runner = new MonRunnable();

// création du thread avec le Runnable en paramètre
Thread t = new Thread(runner);

// lancement (exécution de la méthode run)
t.start();

Quelle approche chosir?

Cette seconde approche de création d'un thread, celle qui utilise un objet Runnable, est préférable à la première pour deux raisons.

D'abord, le fait de dériver une classe X de la classe Thread n'a pas toujours de sens. Imaginez par exemple un jeu où une classe Guerrier contiendrait une animation. Puisqu'une animation doit s'exécuter dans un thread, on pourrait être tenté de dériver Guerrier de Thread, mais un Guerrier est-il une spécialisation de la classe Thread, tout comme une IOException est une spécialisation de la classe Exception? Non.

L'autre inconvénient de la première approche est que l'héritage multiple est interdit en Java. Pour revenir à l'exemple précédent, si on suppose que la classe Guerrier dérive de la classe Personnage, il devient alors impossible de la faire dériver aussi de Thread.