Modifier : je sais ce que fait Thread.interrupt ().
while (! Thread.currentThread (). isInterrupted ())
ne se ferme pas lorsque j'interrompt le fil. L'application crée un Thread
qui lit en continu une URL
. Après 3 secondes, Thread
est interrompu mais continue malheureusement de s'exécuter.
Comment arrêter le thread de s'exécuter?
Code (Main.java, MyRunnable.java):
public class Main { public static void main(String[] args) { MyRunnable runnable = new MyRunnable("http://ninjaflex.com/"); Thread thread = new Thread(runnable); thread.start(); sleep(3000); thread.interrupt(); System.out.println("Thread.interrupt() invoked."); } private static void sleep(long timeMilli) { try { Thread.sleep(timeMilli); } catch (Exception e) { } } } public class MyRunnable implements Runnable { private String website; MyRunnable(String website) { this.website = website; } @Override public void run() { URL url = createUrl(); if (url != null) { while (!Thread.currentThread().isInterrupted()) { sleepOneSec(); readFromUrl(url); System.out.println("Read from " + website); } System.out.println("Script: Interrupted, exiting."); } } private URL createUrl() { URL url = null; try { url = new URL(website); } catch (MalformedURLException e) { System.out.println("Wrong URL?"); } return url; } private void sleepOneSec() { try { Thread.sleep(1000); } catch (Exception e) { System.out.println("Error sleeping"); } } private void readFromUrl(URL url) { InputStream in = null; try { in = url.openStream(); } catch (Exception e) { System.out.println("Exception while url.openStream()."); e.printStackTrace(); } finally { closeInputStream(in); } } private void closeInputStream(InputStream in) { try { in.close(); } catch (IOException e) { System.out.println("Error while closing the input stream."); } } }
3 Réponses :
En gros, votre thread MyRunnable
est interrompu pendant le sommeil. InterreuptedException
est lancé mais intercepté. Soit dit en passant, c'est une mauvaise habitude d'attraper Exception
et vous ne devriez pas le faire.
Depuis le javadoc: "L'état interrompu du thread actuel est effacé lorsque cette exception est levée".
Par conséquent, votre boucle while ne verra jamais le drapeau.
Oh, je n'ai pas vu cela venir. Laissez-moi vérifier en supprimant le sommeil. Mais cela semble logique. Merci pour la contribution.
Ok j'ai raté ce scénario: "Si ce thread est bloqué lors d'un appel des méthodes wait (), wait (long) ou wait (long, int) de la classe Object, ou de la join () , join (long), join (long, int), sleep (long) ou sleep (long, int), méthodes de cette classe, alors son état d'interruption sera effacé et il recevra un InterruptedException. ". Merci encore.
J'ai supprimé MyRunnable.sleepOneSec et votre code a commencé à fonctionner.
Oui, c'est la solution. Le sleep () captait l'interruption mais ensuite l'état de l'interruption a été effacé donc la boucle n'a pas pu être quittée.
Remplacez l'appel à la méthode sleepOneSec
par un simple appel Thread.sleep. Attrapez InterruptedException en dehors de votre boucle while
. Cela entraînera la fermeture naturelle de la boucle:
try { while (true) { Thread.sleep(1000); readFromUrl(url); System.out.println("Read from " + website); } } catch (InterruptedException e) { System.out.println("Script: Interrupted, exiting."); }
Oui, cela fera l'affaire. Mais je m'en fiche de supprimer l'appel de sommeil. Pour être honnête, je l'ai mis là pour ne pas être bombardé par des bûches.
Bombardé par "Script: Interrompu, sortant" vous voulez dire? Changez-le simplement en System.getLogger (Main.class.getName ()). Log (System.Logger.Lev el.DEBUG, "Script: Interrupted, exit.", E);
donc c'est visible uniquement si vous modifiez la configuration de la journalisation.
Merci beaucoup @VGR!
Croiriez-vous que j'ai le même morceau de code dans une application Android et que l'exécution du thread ne s'arrête pas? Astuce, il n'y a pas de Thread.sleep () ici. Demandera probablement une fois de plus.
Je sais ce que Thread.interrupt () fait cher @ PM77-1, mais si j'ai fait quelque chose de mal ici, merci de le partager.