3

我有一个线程可以从 ObjectInputStream 中读取对象:

public void run() {
    try {
        ois = new ObjectInputStream(clientSocket.getInputStream());

        Object o;
        while ((o = ois.readObject()) != null) {
            //do something with object
        }
    } catch (Exception ex) {
        //Log exception
    }
}

readObject 不会抛出 InterruptedException 并且据我所知,当该线程被中断时不会抛出异常。我如何停止这个线程?

4

3 回答 3

4

调用close套接字输入流。你应该能够从另一个线程做到这一点。

于 2010-06-15T16:20:19.970 回答
2

这似乎clientSocket是您唯一的外部可见参考。从另一个线程,调用clientSocket.close()

这将强制在readObject()调用ObjectInputStream抛出 IOException 。这应该会触发你的 catch 块并让你脱离循环。

重新阅读您的问题,您说readObject不会抛出 InterruptedException。在那一点上你是对的:我现在正在查看源代码,readObject它既没有throws也没有明确隐藏InterruptedException.

您应该始终能够通过从另一个线程(或您为读取线程命名的任何名称catch (Exception ex))调用来触发最后一个块(AKA 异常吞噬者)。objectReadingThread.interrupt()引用Javadoc

如果此线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法或 join()、join(long)、join(long, int) 时被阻塞, sleep(long), or sleep(long, int), 这个类的方法,那么它的中断状态会被清除并且会收到一个InterruptedException。

如果此线程在可中断通道上的 I/O 操作中被阻塞,则通道将关闭,线程的中断状态将被设置,并且线程将收到 ClosedByInterruptException。

如果此线程在 Selector 中被阻塞,则线程的中断状态将被设置,并且它将立即从选择操作返回,可能带有非零值,就像调用了选择器的唤醒方法一样。

如果前面的条件都不成立,则将设置该线程的中断状态。

如果这不起作用,我会调查“用对象做某事”块并尝试找到消耗您的中断并忽略它的异常吞噬者。

于 2010-06-16T12:35:18.317 回答
0

您可以尝试捕获InterruptedIOException。我不知道在您的特定情况下它是否有帮助,但它是处理此类情况的最清晰的 Java 方式。

我正在处理一个惊人的案例,尽管以某种神奇的方式捕获了 IOException,但 EOFException 未被捕获,所以我发现你的答案也很有趣。在另一种情况下,尽管不可能是 InterruptException :链接到意外的 InterruptException。这些情况在处理接近 I/O 操作的异常方面存在共同问题。

于 2012-05-29T10:06:03.750 回答