Im Kontext von Java erstelle ich einen neuen Thread zum Lesen von Netzwerkeingaben, wenn ein GUI-Fenster geöffnet wird. Wenn ich das Fenster schließe, möchte ich die Socket-Ressource freigeben und den Thread sofort beenden. Jetzt verwende ich die setSoTimeout-Methode, aber ich möchte nicht auf die Timeout-Ausnahme warten. Könnte jemand einen Vorschlag machen? Vielen Dank!
java
multithreading
sockets
Dingxin Xu
quelle
quelle
Antworten:
Es gibt (möglicherweise) drei Möglichkeiten, dies zu tun:
Durch Aufrufen
Socket.close()
des Sockets werden die zugehörigenInputStream
undOutputStream
Objekte geschlossen und alle in Socket- oder (zugeordneten) Stream-Vorgängen blockierten Threads werden entsperrt. Laut Javadoc werfen Operationen an der Steckdose selbst aSocketException
.Durch das Aufrufen
Thread.interrupt()
wird (unter bestimmten Umständen, die nicht angegeben sind) eine blockierende E / A-Operation unterbrochen, wodurch eine ausgelöst wirdInterruptedIOException
.Beachten Sie die Einschränkung. Anscheinend funktioniert der "Interrupt ()" - Ansatz auf den "meisten" modernen Java-Plattformen nicht. (Wenn jemand anderes die Zeit und die Neigung hätte, könnte er möglicherweise die Umstände untersuchen, unter denen dieser Ansatz funktioniert. Die bloße Tatsache, dass das Verhalten plattformspezifisch ist, sollte jedoch ausreichen, um zu sagen, dass Sie es nur verwenden sollten, wenn Sie nur Ihre Anwendung benötigen an einer bestimmten Plattform zu arbeiten. An diesem Punkt können Sie es einfach selbst "ausprobieren".)
Ein möglicher dritter Weg, dies zu tun, ist anzurufen
Socket.shutdownInput()
und / oderSocket.shutdownOutput()
. Die Javadocs sagen nicht explizit, was mit Lese- und / oder Schreibvorgängen passiert, die derzeit blockiert sind, aber es ist nicht unangemessen zu glauben, dass sie die Blockierung aufheben und auslösen. Wenn der Javadoc jedoch nicht sagt, was passiert, sollte davon ausgegangen werden, dass das Verhalten plattformspezifisch ist.quelle
Ich weiß, dass diese Frage alt ist, aber da niemand das "Geheimnis"
Thread.interrupt()
auf "modernen Plattformen" gelöst zu haben scheint, habe ich einige Nachforschungen angestellt.Dies wird unter Java 8 unter Windows 7 (64-Bit) getestet (dies gilt jedoch möglicherweise auch für andere Plattformen).
Der Aufruf
Thread.interrupt()
ist nicht ein WurfInterruptedIOException
Was passiert , ist , dass dieInputStream.read()
Methode zurückgibt , mit-1
undThread.interrupted()
-Kennzeichen gesetzt ist.Folgendes könnte also als "korrigiertes" Lesen von read () angesehen werden
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; }
quelle
in.read(...)
und die Überprüfung, ob der Thread unterbrochen wurde, wird niemals ausgeführt.