如何立即终止在套接字IO操作上的线程阻塞?

在Java的上下文中,我创build了一个新的线程来读取networkinginput时,打开一个GUI窗口,当我closures窗口,我想释放套接字资源,立即终止线程。 现在我正在使用setSoTimeout方法,但我不想等待超时exception。 有人可以提出一些build议吗? 谢谢!

有(可能)三种方法来做到这一点:

  • 调用套接字上的Socket.close()将closures相关联的InputStreamOutputStream对象,并导致在Socket或(关联)stream操作中阻塞的任何线程被解除阻塞。 根据javadoc,对套接字本身的操作将抛出一个SocketException

  • 调用Thread.interrupt()将会(在某些没有指定的情况下)中断阻塞I / O操作,导致它抛出一个InterruptedIOException

    注意警告。 显然“中断()”方法不适用于“大多数”现代Java平台。 (如果有其他人有时间和倾向,他们可以调查这种方法的工作情况,但是,这一行为是特定于平台的事实应该足以说明,如果你只需要你的应用程序在一个特定的平台上工作,在这一点上,你可以轻松地“自己尝试”)。

  • 可能的第三种方法是调用Socket.shutdownInput()和/或Socket.shutdownOutput() 。 javadocs并没有明确说明当前被阻止的读取和/或写入操作会发生什么情况,但认为它们会解除阻塞并抛出exception并不是不合理的。 但是,如果javadoc没有说明会发生什么,那么这个行为应该被认为是平台特定的。

我知道这个问题很老,但是现在似乎没有人在“现代平台”上解决了Thread.interrupt()的“谜团”,所以我做了一些研究。

这在Windows7(64位)上的Java 8上进行了testing(但对于其他平台也可能如此)。

调用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; }