Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何立即终止套接字IO操作上的线程阻塞?_Java_Multithreading_Sockets - Fatal编程技术网

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

Java 如何立即终止套接字IO操作上的线程阻塞?,java,multithreading,sockets,Java,Multithreading,Sockets,在Java环境中,我创建了一个新线程,在打开GUI窗口时读取网络输入,当我关闭窗口时,我想释放套接字资源并立即终止线程。现在我使用setSoTimeout方法,但我不想等待超时异常。谁能给点建议吗?谢谢 有(可能)三种方法: 调用套接字将关闭关联的InputStream和OutputStream对象,并导致套接字或(关联的)流操作中阻塞的任何线程被解除阻塞。根据javadoc,套接字本身上的操作将抛出一个错误 调用将(在某些未指定的情况下)中断阻塞I/O操作,导致其抛出错误 注意警告。显然,“

在Java环境中,我创建了一个新线程,在打开GUI窗口时读取网络输入,当我关闭窗口时,我想释放套接字资源并立即终止线程。现在我使用setSoTimeout方法,但我不想等待超时异常。谁能给点建议吗?谢谢

有(可能)三种方法:

  • 调用套接字将关闭关联的
    InputStream
    OutputStream
    对象,并导致套接字或(关联的)流操作中阻塞的任何线程被解除阻塞。根据javadoc,套接字本身上的操作将抛出一个错误

  • 调用将(在某些未指定的情况下)中断阻塞I/O操作,导致其抛出错误

    注意警告。显然,“interrupt()”方法在“大多数”现代Java平台上不起作用。(如果其他人有时间和意愿,他们可能会调查这种方法的工作环境。但是,仅仅是行为特定于平台这一事实就足以说明,只有当您只需要应用程序在特定平台上工作时,您才应该使用它。在这一点上,您可以轻松地“尝试”为了你自己。)

  • 第三种可能的方法是调用和/或。javadocs没有明确说明当前被阻止的读和/或写操作会发生什么,但认为它们将取消阻止并引发异常也不是不合理的。但是,如果javadoc没有说明发生了什么,那么应该假定该行为是特定于平台的


我知道这个问题已经很老了,但似乎没有人在“现代平台”上解开
线程中断()的“谜”,所以我做了一些研究

这在Windows7(64位)上的Java8上进行了测试(但在其他平台上也可能如此)

调用
Thread.interrupt()
不会引发
中断异常
发生的情况是,
InputStream.read()
方法返回
-1
,并且设置了
Thread.interrupted()
-标志

因此,以下内容可被视为引发中断异常的“更正”read():

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

我不明白这为什么是-1?!?我认为这个问题非常清楚,而且是在现场。请问,在什么情况下线程.interrupt()会中断阻塞I/O操作?Xu DXn-没有文档记录。一些流实现了这一点,其他流则没有。有关血淋淋的细节,请阅读OpenJDK源代码。我想说的一点是,它可能有效,也可能无效。可以肯定的是,大多数jvm实现都不支持可中断的io操作。我认为sun solaris jvm可能在某一点上支持它。作为这一点的补充,因为现在很多Java程序员实际上都在Android上工作,应该注意的是,Android的某些版本在Socket.close()中有一个bug,它阻止了这项技术的工作。不过,事先调用Socket.shutdownInput()确实有效。@StephenC有三种方法可以做到这一点。关闭输入将导致读取立即解锁并返回EOS状态
ClosedByInterruptException
仅适用于NIO,而不是流或
Sockets
。这个答案值得更多的投票,因为Java在输入/输出流操作期间被中断时的行为并不是许多人所期望的。只有当InputStream提供可以读取的数据时,此方法才有效。否则,该代码将被.read(…)
中的
阻止,并且检查线程是否已中断将永远不会执行。