在Java的上下文中,我在打开GUI窗口时创建一个新线程来读取网络输入,当我关闭窗口时,我想释放套接字资源并立即终止线程。现在我使用setSoTimeout方法,但我不想等待超时异常。有人可以提一些建议吗?谢谢!
答案 0 :(得分:55)
有(可能)三种方法:
在套接字上调用Socket.close()
将关闭关联的InputStream
和OutputStream
对象,并导致在Socket或(关联)流操作中阻塞的任何线程被解除阻塞。根据javadoc,套接字本身的操作将抛出SocketException
。
调用Thread.interrupt()
将(在某些情况下未指定)中断阻塞I / O操作,导致它抛出InterruptedIOException
。
请注意警告。显然,“interrupt()”方法不适用于“大多数”现代Java平台。 (如果其他人有时间和倾向,他们可以调查这种方法的工作环境。但是,这种行为是特定于平台的事实应该足以说明,如果你只需要你的应用程序,你应该只使用它在特定的平台上工作。此时你可以轻松地为自己“尝试”。)
执行此操作的第三种方法是拨打Socket.shutdownInput()
和/或Socket.shutdownOutput()
。 javadocs没有明确说明当前被阻止的读取和/或写入操作会发生什么,但认为它们将解除阻塞并抛出异常并不是不合理的。但是,如果javadoc没有说明会发生什么,那么应该假定该行为是特定于平台的。
答案 1 :(得分:14)
我知道这个问题已经过时了,但似乎没有人能够解决这个问题。 Thread.interrupt()
on"现代平台"我做了一些研究。
这是在Windows7(64位)上的Java 8上测试的(但对其他平台也可能如此)。
致电Thread.interrupt()
不会抛出InterruptedIOException
会发生的是InputStream.read()
方法返回-1
和Thread.interrupted()
- 已设置标记。
因此,以下内容可被视为已经纠正的' read()throw 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;
}