简体   繁体   English

停止不被中断的线程

[英]stop thread that does not get interrupted

I have a thread that sits and reads objects off of an ObjectInputStream: 我有一个线程,它坐在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 does not throw InterruptedException and as far as I can tell, no exception is thrown when this thread is interrupted. readObject不会抛出InterruptedException,据我所知,当此线程被中断时不会抛出异常。 How do I stop this thread? 我该如何阻止这个帖子?

Call close on the socket input stream. 在套接字输入流上调用close You should be able to do that from another thread. 你应该能够从另一个线程做到这一点。

It appears that clientSocket is your only externally visible reference. 似乎clientSocket是您唯一的外部可见引用。 From another thread, call clientSocket.close() 从另一个线程,调用clientSocket.close()

That will force the ObjectInputStream to throw the IOException on the readObject() call. 这将强制ObjectInputStream 在readObject()调用上抛出IOException That should trigger your catch block and get you out of the loop. 这应该触发你的catch阻止并让你走出循环。

Re-reading your question, you say that readObject doesn't throw InterruptedException. 重新阅读你的问题,你说readObject不会抛出InterruptedException。 You're correct in that point: I'm looking at the source for readObject right now and it neither throws nor does it explicitly hide the InterruptedException . 你在这一点上是正确的:我现在正在查看readObject的源代码,它既不会throws也不会显式隐藏InterruptedException

You should always be able to trigger that final catch (Exception ex) block (AKA exception eater) by calling objectReadingThread.interrupt() from another thread (or whatever you name your reading thread). 你应该始终能够通过从另一个线程(或你读取线程命名的任何线程)调用objectReadingThread.interrupt()来触发最终的catch (Exception ex)块(AKA exception eater)。 Quoting the Javadoc : 引用Javadoc

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. 如果在调用Object类的wait(),wait(long)或wait(long,int)方法,或者join(),join(long),join(long,int)方法中阻塞了这个线程,sleep(long)或sleep(long,int),这个类的方法,然后它的中断状态将被清除,它将收到InterruptedException。

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException. 如果此线程在可中断通道上的I / O操作中被阻塞,则通道将关闭,线程的中断状态将被设置,并且线程将收到ClosedByInterruptException。

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked. 如果此线程在Selector中被阻塞,则线程的中断状态将被设置,并且它将立即从选择操作返回,可能具有非零值,就像调用选择器的唤醒方法一样。

If none of the previous conditions hold then this thread's interrupt status will be set. 如果以前的条件都不成立,则将设置该线程的中断状态。

If that isn't working, I would investigate that "do something with object" block and try to find the exception-eater that is consuming your interrupt and ignoring it. 如果这不起作用,我会调查“用对象做一些事情”块并尝试找到消耗中断并忽略它的异常食者。

You can try to catch InterruptedIOException . 您可以尝试捕获InterruptedIOException I don't know if in your particular case it helps but it is a most clear Java way to deal with such cases. 我不知道在您的特定情况下它是否有帮助,但它是处理此类情况的最清晰的Java方法。

I am dealing with a amazing case when despite catching of IOException in some magic way EOFException is uncaught, so I found your answer interesting as well. 我正在处理一个惊人的案例,尽管以某种神奇的方式捕获了IOException EOFException未被捕获,所以我发现你的答案也很有趣。 In another case there is a InterruptException despite it could not be : link to unexpected InterruptException . 在另一种情况下,有一个InterruptException,尽管它不能是: 链接到意外的InterruptException These cases have in common problems with exceptions handling close to I/O operations. 这些情况在接近I / O操作的异常处理中存在常见问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM