我目前正在开发一个守护进程,它将执行很多不同的任务。它是多线程的,旨在处理几乎任何类型的内部错误而不会崩溃。好吧,我即将处理关闭请求,但我不确定应该如何去做。
我有一个关闭挂钩设置,当它被调用时,它会设置一个变量告诉主守护程序循环停止运行。问题是,这个守护进程会产生多个线程,并且它们可能需要很长时间。例如,这些线程之一可能正在转换文档。大多数线程都会很快(我猜不到 10 秒),但有些线程可以持续长达 10 分钟以上。
我现在想做的是,当发送关闭钩子时,在 ThreadGroup.activeCount() 上执行大约 5 秒的循环,并进行 500 毫秒(左右)的睡眠(所有这些线程都在 ThreadGroup 中)和之前在这个循环中,我将向所有线程发送通知,告诉它们已调用关闭请求。然后,无论他们正在做什么清理和关闭,他们都必须立即进行。
还有其他人有什么建议吗?我感兴趣的是像 MySQL 这样的守护进程在被告知停止时会做什么,它会立即停止。如果正在运行 10 个查询,但调用速度非常慢,会发生什么情况?是等待还是结束它们。我的意思是服务器非常快,所以确实没有任何类型的操作是我不能在一秒钟内完成的。现在你可以在 1000 毫秒内完成很多事情。
谢谢
I'm currently working on a daemon that will be doing A LOT of different tasks. It's multi threaded and is being built to handle almost any kind of internal-error without crashing. Well I'm getting to the point of handling a shutdown request and I'm not sure how I should go about doing it.
I have a shutdown hook setup, and when it's called it sets a variable telling the main daemon loop to stop running. The problem is, this daemon spawns multiple threads and they can take a long time. For instance, one of these threads could be converting a document. Most of them will be quick (I'm guessing under 10 seconds), but there will be threads that can last as long as 10+ minutes.
What I'm thinking of doing right now is when a shutdown hook has been sent, do a loop for like 5 seconds on ThreadGroup.activeCount() with a 500ms (or so) Sleep (all these threads are in a ThreadGroup) and before this loop, I will send a notification to all threads telling them a shutdown request has been called. Then they will have to instantly no matter what they're doing cleanup and shutdown.
Anyone else have any suggestions? I'm interested in what a daemon like MySQL for instance does when it gets told to stop, it stops instantly. What happens if like 10 query's are running that are very slow are being called? Does it wait or does it just end them. I mean servers are really quick, so there really isn't any kind of operation that I shouldn't be able to do in less than a second. You can do A LOT in 1000ms now days.
Thanks
发布评论
评论(2)
java.util.并发
包提供了许多实用程序,例如ThreadPoolExecutor
(以及来自Executors
类的其他Executor
实现的各种专用类型)和ThreadPoolExecutor.awaitTermination()
,您可能想要研究一下 - 因为它们提供了与您想要实现的完全相同的功能。这样您就可以专注于实现应用程序/任务的实际功能,而不必担心线程和任务调度等问题。The
java.util.concurrent
package provides a number of utilities, such asThreadPoolExecutor
(along with various specialized types of otherExecutor
implementations from theExecutors
class) andThreadPoolExecutor.awaitTermination()
, which you might want to look into - as they provide the same exact functionality you are looking to implement. This way you can concentrate on implementing the actual functionality of your application/tasks instead of worrying about things like thread and task scheduling.您的线程作业是否可以通过 中断
Thread#interrupt()
?它们是否主要调用本身会抛出 InterruptedException 的函数?如果是这样,则前面提到的java.util.concurrent.ExecutorService#shutdownNow()
是正确的方法。它将中断任何正在运行的线程并返回从未启动的作业列表。同样,如果您坚持使用
ExecutorService#submit()
,可以使用Future#cancel(boolean)
并传递true
来请求中断正在运行的作业。除非您调用的代码超出了您的控制范围并吞没了中断信号(例如,通过捕获
InterruptedException
而不调用Thread.currentThread().interrupt()
),请使用内置的协作中断设施是比引入您自己的标志来近似已有的标志更好的选择。Are your thread jobs amenable to interruption via
Thread#interrupt()
? Do they mostly call on functions that themselves advertise throwingInterruptedException
? If so, then the aforementionedjava.util.concurrent.ExecutorService#shutdownNow()
is the way to go. It will interrupt any running threads and return the list of jobs that were never started.Similarly, if you hang on to the
Future
s produced byExecutorService#submit()
, you can useFuture#cancel(boolean)
and passtrue
to request that a running job be interrupted.Unless you're calling on code out of your control that swallows interrupt signals (say, by catching
InterruptedException
without callingThread.currentThread().interrupt()
), using the built-in cooperative interruption facility is a better choice than introducing your own flags to approximate what's already there.