« Bonjour, Amigo ! Ellie t'a parlé des threads, et je vais te montrer comment travailler avec. Pour créer un nouveau thread, tu dois : »

1) Créer un objet Thread

2) Lui passer la méthode que tu veux exécuter

3) Appeler la méthode start sur l'objet Thread créé.

Prenons l'exemple suivant :

Code Description
class Printer implements Runnable
{
public void run()
{
System.out.println("I’m printer");
}
}
Classe qui implémente l'interface Runnable.
public static void main(String[] args)
{
Printer printer = new Printer();
Thread childThread = new Thread(printer);
childThread.start();
}
1. Crée une instance de la classe Printer, qui implémente la méthode run.
2. Crée un nouvel objet Thread. Nous lui passons le constructeur de l'objet printer, dont la méthode run() doit être appelée.
3. Démarre le nouveau thread en appelant la méthode start().

Les petits programmes Java se composent généralement d'un thread appelé 'thread principal'. Mais les programmes lanceront souvent des threads supplémentaires, appelés 'threads enfants'. Le thread principal exécute la méthode main et se termine. La méthode run de Runnable est la méthode analogue pour les threads enfants.

« Ah, beaucoup de threads signifie beaucoup de méthodes main. »

Création et démarrage de nouveaux threads - 1

Pour dire à un objet Thread quelle méthode spécifique il doit lancer, nous devons lui passer une méthode d'une façon ou d'une autre. En Java, cela se fait avec l'interface Runnable. Cette interface contient une seule méthode abstraite : void run(). La classe Thread a un constructeur Thread(Runnable runnable). Tu peux lui passer tout objet qui implémente l'interface Runnable.

Ta classe doit hériter de Runnable et remplacer sa méthode run. L'appel à cette méthode est ce qui démarre le nouveau thread. Tu peux écrire ce que tu veux dans la méthode run.

Code Description
class Printer implements Runnable
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
Classe qui implémente l'interface Runnable.
public static void main(String[] args)
{
Printer printer1 = new Printer("Nick");
Thread thread1 = new Thread(printer1);
thread1.start();

Printer printer2 = new Printer("Jack");
Thread thread2 = new Thread(printer2);
thread2.start();
}
Crée deux threads, chacun basé sur son propre objet Printer.
public static void main(String[] args)
{
Printer printer = new Printer("Natasha");

Thread thread1 = new Thread(printer);
thread1.start();

Thread thread2 = new Thread(printer);
thread2.start();

Thread thread3 = new Thread(printer);
thread3.start();
}
Crée trois threads à partir d'un seul objet Printer.

De plus, tu peux combiner tout cela dans une seule classe. La classe Thread hérite de l'interface Runnable, il te suffit donc de remplacer sa méthode run :

Autre façon de créer un nouveau thread
class Printer extends Thread
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
Hérite de la classe Thread, qui implémente l'interface Runnable, puis remplace la méthode run.
public static void main(String[] args)
{
Printer printer = new Printer("Jack");
printer.start();

Printer printer2 = new Printer("Jack");
printer2.start();

}
Crée deux threads, chacun basé sur son propre objet Printer.

« C'est une solution plus élégante. »

« Oui, mais elle a ses inconvénients : »

1) Tu pourrais avoir besoin de démarrer plusieurs threads basés sur un seul objet, comme dans l'exemple avec Natasha.

2) Si tu hérites de la classe Thread, tu ne peux pas ajouter une autre classe parente à ta classe.

3) Si ta classe a une classe parente, tu ne peux pas ajouter Thread comme deuxième classe parente.

« En d'autres termes, une fois que la méthode start est appelée, chacun des threads commence à exécuter la méthode run de l'objet passé au constructeur ? »

« Oui. Si rien n'est passé au constructeur, Thread ne fera qu'exécuter sa méthode run interne. »

« Mais pourquoi on ne peut pas simplement appeler la méthode comme ça ? »

Code
public static void main(String[] args)
{
 Printer printer1 = new Printer("Nick");
 printer1.run();
}

« Quand le thread principal atteint la méthode run, son « petit robot » va simplement à l'intérieur et exécute toutes les commandes qui s'y trouvent. Ce n'est qu'après son exécution qu'il revient à la méthode principale et continue à exécuter les autres commandes. Ainsi, il n'y aura pas de deuxième « petit robot » créé. Tous les travaux seront réalisés de manière séquentielle, et non en parallèle (en même temps). »

« Je vois. Peut-on appeler une autre méthode, autre chose que run ? »

« Non, tout est lié à l'interface Runnable, qui ne 'connaît' qu'une méthode : run(). »