5 votes

Comment faire dormir un thread à partir d'un autre thread en Java ?

J'ai deux fils d'exécution (Thread1 et Thread2). Thread2 est à l'écoute d'un événement particulier et lorsque l'événement se produit, il veut arrêter l'exécution de Thread1 et déclencher une action. Une fois l'action terminée, il doit reprendre l'exécution de Thread1 là où il s'est arrêté.

Quelle approche dois-je adopter pour faire cela en Java ?

8voto

JB Nizet Points 250258

La meilleure façon de procéder, selon moi, est de faire en sorte que Thread1 interroge régulièrement une variable d'état pour savoir si on lui a demandé de se mettre en pause. Si c'est le cas, il doit suspendre son exécution en attendant qu'un verrou soit libéré.

Thread2 devrait demander à Thread1 de faire une pause en modifiant la valeur de la variable d'état partagée, puis attendre éventuellement que Thread1 accepte la demande de pause, puis exécuter son action et libérer le verrou sur lequel Thread1 est en attente.

En bref, les deux fils doivent collaborer. À ma connaissance, il n'existe aucun moyen d'interrompre proprement un fil de discussion sans sa collaboration.

5voto

Mathias Schwarz Points 4741

Vous avez (bien entendu) besoin d'une référence au fil de discussion que vous souhaitez interrompre. Vous pouvez le mettre en pause en appelant la méthode "suspend" : http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html#suspend () sur le fil. De la même manière, vous pouvez appeler "resume" pour permettre au thread de s'exécuter à nouveau.

Cependant, il faut savoir que cette méthode est extrêmement vulnérable aux problèmes de blocage, car vous n'avez aucune idée de l'endroit où le fil s'est arrêté.

2voto

Denis Bazhenov Points 2944

Il semble que vous ayez besoin d'une sorte de synchronisation entre les threads. Je suppose que vous voulez T1 ne pas s'endormir, mais attendre jusqu'à ce que T2 effectue une action. Dans ce cas, vous pouvez utiliser n'importe quelle primitive de synchronisation fournie par Java. Par exemple synchronized mot-clé :

class T1 implements Runnable {
  private final Object lock;

  public T1(Object lock) {
    this.lock = lock;
  }

  public function run() {
    while(!currentThread().isInterrupted()) {
      waitForEvent();
      synchronized (lock) {
        // here T2 sleeps and wait until we perform event processing
      }
    }
  }
}

class T2 implements Runnable {
  private final Object lock;

  public T1(Object lock) {
    this.lock = lock;
  }

  public function run() {
    while(!currentThread().isInterrupted()) {
      synchronized (lock) {
        // do some work and release lock
      }
    }
  }
}

Object lock = new Object();
new Thread(new T1(lock)).start();
new Thread(new T2(lock)).start();

Et btw, les méthodes Thread#stop() , Thread#suspend() et Thread#resume() sont obsolètes et il n'est pas recommandé de les utiliser.

1voto

bingjie2680 Points 4518

0voto

Giann Points 1619

Vous pouvez conserver une référence à l'autre fil de discussion dans Thread2 et la mettre en pause. Mais la vraie question est de savoir pourquoi vous avez besoin de deux threads s'ils doivent attendre que l'autre s'exécute ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X