如何立即终止套接字IO操作上的线程阻塞?
在Java的上下文中,我创建了一个新线程来在打开GUI窗口时读取网络输入,当我关闭窗口时,我想释放套接字资源并立即终止线程。现在我正在使用setSoTimeout方法,但我不想等待超时异常。任何人都可以给出一些建议吗?谢谢!
在Java的上下文中,我创建了一个新线程来在打开GUI窗口时读取网络输入,当我关闭窗口时,我想释放套接字资源并立即终止线程。现在我正在使用setSoTimeout方法,但我不想等待超时异常。任何人都可以给出一些建议吗?谢谢!
有(可能)三种方法可以做到这一点:
在套接字上调用 Socket.close()
将关闭关联的和对象,并导致在 Socket 或(关联的)流操作中被阻止的任何线程被取消阻止。根据javadoc,套接字本身的操作将抛出一个SocketException
。InputStream
OutputStream
调用 Thread.interrupt()
将(在某些未指定的情况下)中断阻塞 I/O 操作,导致它引发中断的 IOException
。
请注意注意事项。显然,“interrupt()”方法不适用于“大多数”现代Java平台。(如果其他人有时间和意愿,他们可以调查这种方法起作用的情况。但是,仅凭该行为是特定于平台的这一事实就足以说明,仅当您只需要应用程序在特定平台上工作时,才应使用它。在这一点上,您可以轻松地自己“尝试一下”。
可能的第三种方法是调用 Socket.shutdownInput()
和/或 Socket.shutdownOutput()。
javadocs没有明确说明当前被阻止的读取和/或写入操作会发生什么,但是认为它们将取消阻止并引发异常并不是没有道理的。但是,如果javadoc没有说明发生了什么,那么应该假设该行为是特定于平台的。
我知道这个问题很老了,但由于似乎没有人解决“现代平台”的“谜团”,我做了一些研究。Thread.interrupt()
这在Windows7(64位)上的Java 8上进行了测试(但对于其他平台也可能如此)。
调用不会引发一个 发生的事情是该方法返回并设置了 -flag。Thread.interrupt()
InterruptedIOException
InputStream.read()
-1
Thread.interrupted()
因此,以下情况可以被认为是“已更正”的 read() 抛出: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;
}