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

时间:2010-12-13 02:19:37

标签: java multithreading sockets

在Java的上下文中,我在打开GUI窗口时创建一个新线程来读取网络输入,当我关闭窗口时,我想释放套接字资源并立即终止线程。现在我使用setSoTimeout方法,但我不想等待超时异常。有人可以提一些建议吗?谢谢!

2 个答案:

答案 0 :(得分:55)

有(可能)三种方法:

  • 在套接字上调用Socket.close()将关闭关联的InputStreamOutputStream对象,并导致在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()方法返回-1Thread.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;
}
相关问题