Interaction entre threads
Maintenant qu'on a vu comment arrêter proprement un thread, on va s'intéresser à un autre problème de contrôle, à savoir cela de gérer l'interaction entre threads. Pour ce faire, il existe un mécanisme dans Java qu'on va étudier dans cette section. Ce mécanisme est à la base des nombreuses formes d'interaction courantes en programmation concurrente et il est donc très intéressant de bien le comprendre.
Tout ce qu'on va voir ici se base sur des méthodes de la classe Object
:
public final void wait() throws InterruptedException; public final void notify(); public final void notifyAll();
Pour qu'un thread puisse appeler une de ces méthodes sur un objet, il faut que le thread possède le lock de l'objet. L'appel doit donc se faire dans un bloc synchronized
sur l'objet, comme on l'a vu au chapitre 2. Sinon, une exception de type IllegalMonitorStateException
sera levée (exception hors-contrôle).
Endormir un thread
Tous les objets possèdent, outre un lock, un ensemble de threads en attente. Pour un objet o
, lorsqu'on exécute la méthode o.wait()
, le thread qui fait l'appel passe dans l'état Waiting. De plus, le lock de o
que le thread possédait est libéré.
Voyons cela sur l'exemple suivant. La première chose qui est faite est d'obtenir le lock de l'objet courant. Ensuite, on appelle la méthode wait
sur ce même objet. À ce moment, le thread qui exécute cette tâche est endormi (passe dans l'état Waiting) et ajouté à la liste d'attente de l'objet courant. Tant qu'il n'est pas réveillé, il ne sera donc plus exécuté sur la machine. De plus, une fois ajouté à la liste d'attente, sachez que le thread libère le lock qu'il possédait.