Meilleure façon de signaler à un autre thread de s’arrêter?

Commencé plusieurs threads de travail, il faut leur demander de s’arrêter. Étant donné que certains des fils vont dormir pendant un certain temps avant le prochain cycle de travail, vous devez trouver un moyen de les avertir même quand ils sont en train de dormir.

Si c’était de la programmation Windows, je pourrais utiliser les fonctions Event et Wait. En Java, je le fais en utilisant un object CountDownLatch qui compte 1. Cela fonctionne, mais vous ne vous sentez pas élégant, surtout je dois vérifier la valeur de comptage pour voir s’il faut quitter:

run(){ while(countDownLatch.count()>0){ //working // ... countDownLatch.wait(60,TimeUnit.SECONDS); } } 

Le sémaphore est un autre choix, mais vous ne vous sentez pas très bien non plus. Je me demande s’il y a une meilleure façon de faire cela? Je vous remercie.

La meilleure approche consiste à interrupt() le thread de travail.


 Thread t = new Thread(new Runnable(){ @Override public void run(){ while(!Thread.currentThread().isInterrupted()){ //do stuff try{ Thread.sleep(TIME_TO_SLEEP); }catch(InterruptedException e){ Thread.currentThread().interrupt(); //propagate interrupt } } } }); t.start(); 

Et tant que vous avez une référence à t , tout ce qui est nécessaire pour “arrêter” t est d’appeler t.interrupt() .

Utilisez le cadre d’interruption de thread intégré. Pour arrêter un thread de travail, appel à workerThread.interrupt() , certaines méthodes (telles que Thread.sleep ()) émettent une exception interrompue. Si vos threads n’appellent pas les méthodes pouvant être interrompues, vous devez vérifier le statut interrompu.

Dans le fil de travail:

 run() { try { while(true) { //do some work Thread.sleep(60000); } } catch(InterruptedException e) { //told to stop working } } 

Le bon moyen est d’ interrupt() threads interrupt() , et à l’intérieur du cycle de créer un cycle comme

 try { while (!Thread.interrupted()) { ... } } catch (InterruptedException e) { // if interrupted in sleep } 

Gardez à l’esprit les deux cas où interrompez-vous:

  • si vous sleep ou wait InterruptedException sera levée;
  • dans d’autres cas, un drapeau interrompu sera défini pour le fil que vous devez vérifier vous-même.

Pour avoir un pool de threads, j’utiliserais le service ExecutorService ou ScheduledExecutorService pour les tâches différées / périodiques.

Quand vous voulez que les travailleurs arrêtent, vous pouvez utiliser

 executorService.shutdown(); 

L’autre meilleure approche serait d’utiliser la méthode interrupt( ) .

Voici comment un fil utilise ces informations pour déterminer s’il doit ou non se terminer:

 public class TestAgain extends Thread { // ... // ... public void run( ) { while (!isInterrupted( )) { // ... } } }