Come terminare istantaneamente un blocco thread sul funzionamento del socket IO?

Nel contesto di Java, creo un nuovo thread per leggere l’input di rete quando apro una finestra GUI e quando chiudo la finestra, voglio rilasciare la risorsa socket e terminare immediatamente il thread. Ora sto usando il metodo setSoTimeout, ma non voglio aspettare l’eccezione di timeout. Qualcuno potrebbe dare qualche suggerimento? Grazie!

    Ci sono (potenzialmente) tre modi per farlo:

    • Chiamando Socket.close() sul socket si chiuderanno gli oggetti InputStream e OutputStream associati e si causerà il blocco di qualsiasi thread bloccato in Socket o nelle operazioni di stream (associate). Secondo javadoc, le operazioni sul socket stesso generano un SocketException .

    • La chiamata a Thread.interrupt() (in alcune circostanze non specificate) interromperà un’operazione di I / O di blocco, causando il lancio di un’interrupttionIOException.

      Nota l’avvertenza. Apparentemente l’approccio “interrupt ()” non funziona sulla “maggior parte” delle moderne piattaforms Java. (Se qualcun altro avesse il tempo e l’inclinazione, potrebbero indagare sulle circostanze in cui questo approccio funziona, ma il semplice fatto che il comportamento sia specifico della piattaforma dovrebbe essere sufficiente per dire che dovresti usarlo solo se hai bisogno della tua applicazione lavorare su una piattaforma specifica. A quel punto puoi facilmente “provarlo” per te.)

    • Un ansible terzo modo per farlo è chiamare Socket.shutdownInput() e / o Socket.shutdownOutput() . I javadoc non dicono esplicitamente cosa succede con le operazioni di lettura e / o scrittura che sono attualmente bloccate, ma non è irragionevole pensare di sbloccare e lanciare un’eccezione. Tuttavia, se la javadoc non dice cosa succede, si deve presumere che il comportamento sia specifico della piattaforma.

    So che questa domanda è vecchia ma siccome nessuno sembra aver risolto il “mistero” di Thread.interrupt() su “piattaforms moderne” ho fatto qualche ricerca.

    Questo è testato su Java 8 su Windows 7 (64 bit) (ma probabilmente sarà vero anche per altre piattaforms).

    Chiamare Thread.interrupt() non lancia un InterruptedIOException Ciò che accade è che il metodo InputStream.read() restituisce con -1 e Thread.interrupted() -flag è impostato.

    Quindi il seguente potrebbe essere considerato un read () corretto () che lancia 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; }