Comment arrêter un thread en attente d’une lecture bloquante en Java?

J’ai un fil qui exécute le code suivant:

public void run() { try { int n = 0; byte[] buffer = new byte[4096]; while ((n = in.read(buffer)) != -1) { out.write(buffer, 0, n); out.flush(); } } catch (IOException e) { System.out.println(e); } } 

in est System.in . Comment puis-je arrêter un tel fil avec grâce? Ni fermer System.in , ni utiliser Thread.interrupt semble fonctionner.

En effet, la lecture de System.in (InputStream) est une opération bloquante.

Regardez ici Est-il possible de lire un InputStream avec un délai d’attente?

Vous êtes tombé sur un virus de 9 ans que personne ne veut réparer. Ils disent qu’il y a des solutions de contournement dans ce rapport de bogue . Très probablement, vous devrez trouver un autre moyen de régler le délai d’attente (une attente occupée semble inévitable).

Vous pouvez utiliser la méthode available () (non bloquante) pour vérifier s’il y a quelque chose à lire auparavant.

En pseudo-java:

 //... while(running) { if(in.available() > 0) { n = in.read(buffer); //do stuff with the buffer } else { Thread.sleep(500); } } //when running set to false exit gracefully here... 

J’ai eu le même problème aujourd’hui, et in.ready() comment je l’ai corrigé, en utilisant in.ready() :

 public void run() { Ssortingng line; // Some code while(!Thread.currentThread().isInterrupted()){ try { if (in.ready()) { line = in.readLine(); } } catch (Exception e) { try { Thread.currentThread().wait(500); } catch (InterruptedException e1) { // Do what we want when thread is interrupted } } } } 

Est-il sécuritaire de fermer le stream dans un autre thread? Ça marche pour moi. Dans ce cas, in.read(...) lève l’exception SocketException .

Si vous souhaitez laisser à un utilisateur le temps de saisir des données, par exemple pour autoriser le remplacement de valeurs par défaut ou l’interruption d’un processus automatisé, attendez d’abord et vérifiez l’entrée disponible après la pause:

 System.out.println("Enter value+ENTER within 5 Seconds to override default value: "); try{ Thread.sleep(5000); } catch {InterruptedException e){} try{ int bytes = System.in.available(); if (bytes > 0) { System.out.println("Using user entered data ("+size+" bytes)"); } else { System.out.println("Using default value"); } } catch(IOException e) { /*handle*/ } 

vous pouvez utiliser un drapeau externe pour cela

 boolean flag = true; public void run() { try { int n = 0; byte[] buffer = new byte[4096]; while ((n = in.read(buffer)) != -1 && flag) { out.write(buffer, 0, n); out.flush(); } } catch (IOException e) { System.out.println(e); } }