web-dev-qa-db-fra.com

Comment arrêter tous les threads exécutables dans Java classe exécuteur?

final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future<?> future = executor.submit(myRunnable);
executor.shutdown();
if(executor.awaitTermination(10, TimeUnit.SECONDS)) {
  System.out.println("task completed");
}else{
  System.out.println("Executor is shutdown now");
}

//MyRunnable method is defined as task which I want to execute in a different thread.

Voici la méthode run de la classe exécuteur:

public void run() {
try {
     Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
}}

Ici, il attend 20 seconde mais quand j'exécute le code, il lance une exception:

Java.lang.InterruptedException: sleep interrupted
at Java.lang.Thread.sleep(Native Method)

Je ne parviens pas à fermer le thread simultané en ruine dans Java Executor class. Voici mon flux de code:

  • Création d'un nouveau thread avec Java classe exécuteur pour exécuter une tâche, c'est-à-dire écrit en MyRunnable
  • executor attendez 10 secondes pour terminer les tâches.
  • Si la tâche est terminée, le thread exécutable a également été interrompu.
  • Si la tâche n'est pas terminée dans les 10 secondes, la classe executor doit terminer le thread.

Tout fonctionne bien sauf la fin des tâches dans le dernier scénario. Comment dois-je procéder?

14
Amit Pal

La méthode shutDown() empêche simplement la planification de tâches supplémentaires. Au lieu de cela, vous pouvez appeler shutDownNow() et vérifier l'interruption du thread dans votre Runnable.

// in your Runnable...
if (Thread.interrupted()) {
  // Executor has probably asked us to stop
}

Un exemple, basé sur votre code, pourrait être:

final ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
  public void run() {
    try {
      Thread.sleep(20 * 1000);
    } catch (InterruptedException e) {
      System.out.println("Interrupted, so exiting.");
    }
  }
});

if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
  System.out.println("task completed");
} else {
  System.out.println("Forcing shutdown...");
  executor.shutdownNow();
}
16
Duncan Jones

C'est généralement une mauvaise idée de terminer un thread en cours d'exécution de l'extérieur, car vous ne connaissez pas l'état dans lequel le thread est actuellement. Il est possible qu'il doive effectuer quelques nettoyages, et il ne pourra pas le faire lorsque vous l'avez fermé de force. C'est pourquoi toutes les méthodes de Thread qui le font sont marquées comme obsolètes .

Il est préférable d'utiliser l'une des nombreuses techniques disponibles pour la communication interprocessus pour signaler à la procédure exécutée dans le thread lui-même qu'il doit abandonner son travail et quitter normalement. Une façon de procéder consiste à ajouter une méthode abort() à votre exécutable, qui déclenche un indicateur déclaré comme volatile. La boucle interne de votre Runnable vérifie ce drapeau et quitte (de manière contrôlée) lorsque ce drapeau est levé.

2
Philipp