web-dev-qa-db-fra.com

Comment un fil devrait se fermer en Java?

C'est une question courte. À un moment donné, mon fil comprend qu'il devrait y avoir suicide. Quelle est la meilleure façon de le faire:

  1. Thread.currentThread (). Interruption ();
  2. revenir;

À propos, pourquoi dans le premier cas, nous devons utiliser currentThread? Est-ce que Thread ne fait pas référence au thread actuel?

63
Roman

Si vous voulez mettre fin au thread, le retour est correct. Vous n'avez PAS besoin d'appeler Thread.currentThread().interrupt() (cela ne fera rien de mal cependant. C'est juste que vous n'en avez pas besoin.) C'est parce que interrupt() est essentiellement utilisé pour notifier le propriétaire du fil (bien, pas 100% précis, mais en quelque sorte). Étant donné que vous êtes le propriétaire du fil et que vous avez décidé de mettre fin au fil, il n'y a personne à notifier, vous n'avez donc pas besoin de l'appeler.

À propos, pourquoi dans le premier cas, nous devons utiliser currentThread? Est-ce que Thread ne fait pas référence au thread actuel?

Oui, ça ne va pas. Je suppose que cela peut être déroutant parce que, par exemple, Thread.sleep () affecte le thread actuel, mais Thread.sleep () est une méthode statique.

Si vous n'êtes PAS le propriétaire du fil de discussion (par exemple, si vous n'avez pas étendu Thread et codé a Runnable etc.), vous devriez faire

Thread.currentThread().interrupt();
return;

De cette façon, quel que soit le code qui appelle votre exécutable, il saura que le thread est interrompu = (normalement) devrait arrêter ce qu'il est en train de faire et se terminer. Comme je l'ai dit plus tôt, il ne s'agit cependant que d'un mécanisme de communication. Le propriétaire peut simplement ignorer le statut interrompu et ne rien faire .. mais si vous définissez le statut interrompu, quelqu'un pourrait vous en remercier à l'avenir.

Pour la même raison, vous ne devriez jamais faire

Catch(InterruptedException ie){
     //ignore
}

Parce que si vous le faites, vous arrêtez le message là-bas. Au lieu de cela on devrait faire

Catch(InterruptedException ie){
    Thread.currentThread().interrupt();//preserve the message
    return;//Stop doing whatever I am doing and terminate
}
63
Enno Shioji

Si la méthode run se termine, le thread se terminera.

Si vous utilisez une boucle, procédez comme suit:

// In your imlemented Runnable class:
private volatile boolean running = true;

public void run()
{
   while (running)
   {
      ...
   }
}


public void stopRunning()
{
    running = false;
}

Bien sûr, le retour est le meilleur moyen.

18
Martijn Courteaux

Si vous êtes au plus haut niveau - ou êtes capable de le faire proprement , vous allez au plus haut niveau - du fil de discussion, alors il vous suffit de revenir à Nice. Lancer une exception n'est pas aussi simple, car vous devez être capable de vérifier que rien ne va capturer l'exception et l'ignorer.

La raison pour laquelle vous devez utiliser Thread.currentThread() pour appeler interrupt() est que interrupt() est une méthode d'instance - vous devez l'appeler sur le thread que vous souhaitez interrompre. , qui dans votre cas se trouve être le fil actuel. Notez que l'interruption ne sera remarquée que la prochaine fois que le thread bloquera (par exemple pour IO ou pour un moniteur) de toute façon - cela ne signifie pas que l'exception est levée immédiatement.

5
Jon Skeet

Si vous appelez simplement interrupt(), le thread ne sera pas automatiquement fermé. Au lieu de cela, le thread pourrait même continuer vivre, si isInterrupted() est implémenté en conséquence. Le seul moyen de garantir close un thread, comme demandé par OP, est

Thread.currentThread().stop();

La méthode est obsolète, cependant.

L'appel de return ne renvoie que la méthode actuelle. Cela ne met fin au fil que si vous êtes au plus haut niveau.

Néanmoins, vous devriez travailler avec interrupt() et construire votre code autour de celui-ci.

5
Blauhirn

Le fil est une classe, pas une instance; currentThread () est une méthode statique qui renvoie l'instance de thread correspondant au thread appelant.

Utilisez (2). interrupt () est un peu brutal pour une utilisation normale.

1
Marcelo Cantos