2

我目前正在开发一个守护进程,它将执行很多不同的任务。它是多线程的,并且正在构建以处理几乎任何类型的内部错误而不会崩溃。好吧,我正在处理关闭请求,但我不确定我应该如何去做。

我有一个关闭挂钩设置,当它被调用时,它会设置一个变量,告诉主守护程序循环停止运行。问题是,这个守护进程产生了多个线程,它们可能需要很长时间。例如,这些线程之一可能正在转换文档。他们中的大多数会很快(我猜不到 10 秒),但会有一些线程可以持续长达 10 分钟以上。

我现在正在考虑做的是,当发送关闭挂钩时,在 ThreadGroup.activeCount() 上循环 5 秒左右,睡眠时间为 500 毫秒(左右)(所有这些线程都在 ThreadGroup 中)和之前在这个循环中,我将向所有线程发送通知,告诉它们已调用关闭请求。然后,无论他们在做什么清理和关闭,他们都必须立即进行。

还有人有什么建议吗?我对像 MySQL 这样的守护进程在被告知停止时会做什么感兴趣,它会立即停止。如果正在调用 10 个运行速度非常慢的查询,会发生什么情况?它是等待还是只是结束它们。我的意思是服务器真的很快,所以真的没有任何类型的操作我不应该在不到一秒的时间内完成。现在你可以在 1000 毫秒内做很多事情。

谢谢

4

2 回答 2

2

java.util.concurrent软件包提供了许多实用程序,例如ThreadPoolExecutor(以及该类中各种特殊类型的其他Executor实现Executors)和ThreadPoolExecutor.awaitTermination(),您可能想要查看它们 - 因为它们提供了您希望实现的相同功能。通过这种方式,您可以专注于实现应用程序/任务的实际功能,而不必担心线程和任务调度之类的事情。

于 2009-12-07T23:30:23.290 回答
1

您的线程作业是否可以通过 中断Thread#interrupt()?他们主要调用自己宣传 throwing 的函数InterruptedException吗?如果是这样,那么前面提到java.util.concurrent.ExecutorService#shutdownNow()的就是要走的路。它将中断任何正在运行的线程并返回从未启动的作业列表。

同样,如果您挂在Futures 生成的 s 上ExecutorService#submit(),您可以使用Future#cancel(boolean)和 passtrue来请求中断正在运行的作业。

除非您正在调用超出您控制的代码来吞下中断信号(例如,通过捕获InterruptedException而不调用Thread.currentThread().interrupt()),否则使用内置的协作中断工具比引入您自己的标志来近似已经存在的内容是更好的选择。

于 2009-12-08T01:23:57.877 回答