Comment arrêter un thread en attente dans une opération de lecture bloquante en Java?

j'ai un thread 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);
    }
}

inSystem.in. Comment puis-je arrêter un tel fil avec grâce? Ni de fermeture System.in, ni à l'aide de Thread.interrupt semblent fonctionner.

17
demandé sur vitaut 2010-11-15 11:05:03

7 réponses

c'est à cause du système de lecture.in (InputStream) est une opération de blocage.

Regarde ici Est-il possible de lire à partir d'un InputStream avec un délai d'attente?

7
répondu PeterMmm 2017-05-23 12:00:31

Vous avez trébuché sur un de 9 ans bug personne n'est prêt à les réparer. On dit qu'il y a des solutions de rechange en ce rapport de bogue. Très probablement, vous aurez besoin de trouver un autre moyen de mettre le temps d'arrêt (l'attente occupée semble inévitable).

6
répondu Denis Tulskiy 2010-11-15 09:10:39

Vous pouvez utiliser la méthode disponible () (qui n'est pas bloquante) pour vérifier s'il y a quelque chose à lire à l'avance.

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...
2
répondu Paolo 2010-11-15 08:27:09

j'ai eu le même problème aujourd'hui, et c'est comme ça que je l'ai corrigé, en utilisant in.ready():

public void run() {
    String 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
            }
        }
    }
}
1
répondu Nans 2012-03-01 15:22:25

Est-il sécuritaire de proximité dans les flux dans l'autre thread? Il fonctionne pour moi. Dans ce cas, in.read(...) lance l'exception SocketException.

1
répondu tdx 2012-03-02 14:14:51

si vous voulez donner à un utilisateur un certain temps pour entrer des données - peut-être pour autoriser des valeurs par défaut ou interrompre un processus automatisé -, alors attendez d'abord et vérifiez les entrées disponibles 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*/ }
0
répondu Andreas_D 2010-11-15 08:42:21

vous pouvez utiliser un externe drapeau pour cette

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); 
    } 
} 
-3
répondu asela38 2010-11-15 08:42:20