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