当有等待线程时如何优雅地降级程序?
我知道优雅地终止线程的构造:
public class Foo implements Runnable {
private volatile boolean stop = false;
public void stop() {
stop = true;
}
public void run() {
while (!stop) {
...
}
}
}
但是如果某个线程正在某个对象内等待某些东西(使用wait()
,没有时间限制),那么这个构造对于停止没有用这个线程,因为他已经超过了 while 循环中的条件,所以他将永远继续下去。
那么,停止等待线程的正确方法是什么?
I know the construct of terminating a thread gracefully:
public class Foo implements Runnable {
private volatile boolean stop = false;
public void stop() {
stop = true;
}
public void run() {
while (!stop) {
...
}
}
}
But if some thread is waiting for something, inside some object (using wait()
, without time limit), then this construct won't be useful to stopping this thread, because he is already past the condition in the while loop, so he will continue forever.
So, what is the right way to stop the waiting threads?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果线程实际上在等待某些东西,您应该调用方法Thread.interrupt() 中断线程。不要在 while 循环中检查自定义变量,而是使用 Thread.isInterrupted() 或 Thread.interrupted() - 一个会重置中断标志,另一个则不会。
如果您正在等待某些事情,我假设您必须捕获 InterruptedException,不是吗?
If the Thread is actually waiting for something, you should call the method Thread.interrupt() to interrupt the thread. Instead of checking for your custom variable in the while loop, use Thread.isInterrupted() or Thread.interrupted() - one resets the interruption flag, the other doesn't.
If you are waiting on something, I assumed you had to catch the InterruptedException, didn't you?
如果您不希望线程无限期地等待,那么首先不要对它们进行编码。你正在编写他们的代码,所以编写它来完成你实际要做的事情,这样你就不必尝试从外部修复它。
If you don't want your threads to wait indefinitely, don't code them to do that in the first place. You're writing their code, so write it to do what you actually so you don't have to try to fix it from the outside.
每个表现良好的阻塞方法都会声明一个受检查的异常
InterruptedException
,它的确切目的是:通知线程在被阻塞时已被中断。您必须捕获此异常,实际上这可以替换您的
stop
字段。例如,让我们考虑一个日志系统,它会将消息写入专用线程上的文件(这样,花在 IO 上的时间就不会干扰您的应用程序——假设它不是 IO 密集型的应用程序)。
每个线程都有一个可通过 Thread.currentThread().isInterrupted() 读取的中断标志。您可以尝试如下操作:
最后,为了正常关闭应用程序,您必须确保在关闭 JVM 之前终止该线程。为此,您必须绝对确定在以任何可能的方式关闭之前调用
stop()
,或者您可以通过向类中添加类似以下实例初始值设定项的内容来注册关闭挂钩:将强制 JVM 在终止之前调用 close() (因此中断线程、刷新并关闭文件)。
Every well-behaved blocking method declares a the checked exception
InterruptedException
, which serves this exact purpose: to notify that the thread has been interrupted while it was blocked.You have to catch this exception, and actually this could replace your
stop
field.For instance, let's consider a logging system that will write messages to a file on a dedicated thread (so that the time spent on IO will not interfere in your application -- assuming it is not IO heavy).
Every thread has an initerrupted flag that can be read through
Thread.currentThread().isInterrupted()
. You try something like this:Finally, for a graceful shutdown of your application, you must be sure to terminate this thread before letting the JVM shutdown. To do so, you must either be absolutely certain to call
stop()
before shutting down in any possible way, or you could register a shutdown hook, by adding something like this instance initializer to the class:This will force the JVM to call close() (therefore interrupting the thread, flushing and closing the file) before terminating.
这一切都取决于您为什么必须在线程中等待。如果线程正在等待不可中断的IO,那么你可以看看停止/中断线程在等待来自套接字的输入时被阻塞
否则,这完全取决于您在线程中的等待方式。您可以使用
wait(1000)
,然后检查该标志并再等待一段时间。您可以等待来自阻塞队列的消息,可以使用锁/条件,甚至等待/通知也可以在这种情况下工作,您需要正确处理中断。That all depends on why you have to wait in your thread. If the thread is waiting on an uninterruptible IO, then you can take a look at Stop/Interrupt threads blocked on waiting input from socket
Otherwise it all depends on how you wait in the thread. You could use
wait(1000)
, then check for the flag and wait some more. You could wait for a message from a blocking queue, you could use locks/conditions, evenwait/notify
could work in this case you would need to handle interrupts properly.