Comment mettre fin à un blocage de thread sur le fonctionnement du socket IO instantanément?

Dans le contexte de Java, je crée un nouveau thread pour lire les entrées réseau lorsque vous ouvrez une fenêtre graphique, et lorsque je ferme la fenêtre, je souhaite libérer la ressource socket et terminer le thread immédiatement. Maintenant, j’utilise la méthode setSoTimeout, mais je ne veux pas attendre l’exception de délai d’attente. Quelqu’un pourrait-il donner une suggestion? Merci!

Il y a (potentiellement) trois façons de le faire:

  • L’appel de Socket.close() sur le socket ferme les objects InputStream et OutputStream , et provoque le OutputStream des threads bloqués dans les opérations Socket ou les stream (associés). Selon le javadoc, les opérations sur le socket proprement dit SocketException une SocketException .

  • L’appel de Thread.interrupt() (dans certaines circonstances non spécifiées) interrompt une opération d’E / S bloquante, provoquant une InterruptedIOException .

    Notez la mise en garde. Apparemment, l’approche “interruption ()” ne fonctionne pas sur “la plupart” des plateformes Java modernes. (Si quelqu’un d’autre avait le temps et l’inclination, il pourrait éventuellement enquêter sur les circonstances dans lesquelles cette approche fonctionne. Cependant, le simple fait que le comportement soit spécifique à la plateforme devrait suffire à dire que vous ne devriez l’utiliser que si vous avez seulement besoin de votre application pour travailler sur une plate-forme spécifique, à quel point vous pouvez facilement “l’essayer” pour vous-même.)

  • Une troisième méthode possible consiste à appeler Socket.shutdownInput() et / ou Socket.shutdownOutput() . Les javadocs ne disent pas explicitement ce qui se passe avec les opérations de lecture et / ou d’écriture actuellement bloquées, mais il n’est pas déraisonnable de penser qu’elles vont débloquer et lancer une exception. Cependant, si le javadoc ne dit pas ce qui se passe, le comportement doit être supposé être spécifique à la plate-forme.

Je sais que cette question est ancienne mais comme personne ne semble avoir résolu le “mystère” de Thread.interrupt() sur les “plates-formes modernes”, j’ai fait quelques recherches.

Ceci est testé sur Java 8 sur Windows 7 (64 bits) (mais cela sera peut-être vrai pour les autres plates-formes).

L’appel de Thread.interrupt() ne Thread.interrupt() pas d’ InterruptedIOException InputStream.read() méthode InputStream.read() renvoie la valeur -1 et Thread.interrupted() -flag est définie.

Donc, ce qui suit pourrait être considéré comme une lecture () corrigée en lançant InterruptedIOException :

 static final int read(Socket socket, byte[] inData) throws SocketTimeoutException, // if setSoTimeout() was set and read timed out InterruptedIOException, // if thread interrupted IOException // other erors { InputStream in = socket.getInputStream(); int readBytes = in.read( inData, 0, inData.length); if ( Thread.interrupted() ) { throw new InterruptedIOException( "Thread interrupted during socket read"); } return readBytes; }