Java 如何立即终止阻塞套接字 IO 操作的线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4425350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to terminate a thread blocking on socket IO operation instantly?
提问by Dingxin Xu
In the context of Java, I create a new thread to read network input when open a GUI window, and when i close the window, i want to release the socket resource and terminate the thread immediately. Now i am using setSoTimeout method, but i don't want to wait the timeout exception. Could anybody give some suggestion? Thanks!
在 Java 的上下文中,我创建了一个新线程来在打开 GUI 窗口时读取网络输入,当我关闭窗口时,我想释放套接字资源并立即终止线程。现在我正在使用 setSoTimeout 方法,但我不想等待超时异常。有人可以给一些建议吗?谢谢!
采纳答案by Stephen C
There are (potentially) three ways to do this:
有(可能)三种方法可以做到这一点:
Calling
Socket.close()
on the socket will close the associatedInputStream
andOutputStream
objects, and cause any threads blocked in Socket or (associated) stream operations to be unblocked. According to the javadoc, operations on the socket itself will throw aSocketException
.Calling
Thread.interrupt()
will (under some circumstances that are not specified) interrupt a blocking I/O operation, causing it to throw anInterruptedIOException
.Note the caveat. Apparently the "interrupt()" approach doesn't work on "most" modern Java platforms. (If someone else had the time and inclination, they could possible investigate the circumstances in which this approach works. However, the mere fact that the behavior is platform specific should be sufficient to say that you should only use it if you only need your application to work on a specific platform. At which point you can easily "try it" for yourself.)
A possible third way to do this is to call
Socket.shutdownInput()
and/orSocket.shutdownOutput()
. The javadocs don't say explicitly what happens with read and/or write operations that are currently blocked, but it is not unreasonable to think that they will unblock and throw an exception. However, if the javadoc doesn't say what happens then the behavior should be assumed to be platform specific.
调用
Socket.close()
套接字将关闭关联的InputStream
和OutputStream
对象,并导致在 Socket 或(关联的)流操作中被阻塞的任何线程被解除阻塞。根据 javadoc,对套接字本身的操作将抛出一个SocketException
.调用
Thread.interrupt()
将(在某些未指定的情况下)中断阻塞 I/O 操作,导致它抛出一个InterruptedIOException
.请注意警告。显然,“interrupt()”方法不适用于“大多数”现代 Java 平台。(如果其他人有时间和兴趣,他们可以调查这种方法工作的情况。但是,行为是特定于平台的这一事实应该足以说明您应该只在您只需要应用程序时使用它在特定平台上工作。此时您可以轻松地为自己“尝试”。)
可能的第三种方法是调用
Socket.shutdownInput()
和/或Socket.shutdownOutput()
. javadocs 没有明确说明当前被阻塞的读和/或写操作会发生什么,但认为它们会解除阻塞并抛出异常并不是没有道理的。但是,如果 javadoc 没有说明会发生什么,则应假定行为是特定于平台的。
回答by raudi
I know this question is old but as nobody seems to have solved the "mystery" of Thread.interrupt()
on "modern platforms" I did some research.
我知道这个问题很老,但由于似乎没有人解决了Thread.interrupt()
“现代平台”上的“谜团”,我做了一些研究。
This is tested on Java 8 on Windows7 (64-bit) (but it will possibly be true for other platforms as well).
这在 Windows7(64 位)上的 Java 8 上进行了测试(但对于其他平台也可能如此)。
Calling Thread.interrupt()
does notthrow an InterruptedIOException
What happens is that the InputStream.read()
method returns with -1
and Thread.interrupted()
-flag is set.
调用Thread.interrupt()
并不会引发InterruptedIOException
什么情况是,该InputStream.read()
方法返回与-1
和Thread.interrupted()
-flag设置。
So the following could be considered a 'corrected' read() throwing InterruptedIOException
:
因此,以下内容可以被视为“更正”的 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;
}