关闭 ExecutorService
Shutting down ExecutorService
根据 documentation,当 shutdown()
被调用时,任何已经提交的任务(我假设通过 submit()
或 execute
)将被执行。当调用 shutdownNow()
时,执行器将暂停所有等待处理的任务,并尝试停止正在执行的任务。
我想澄清的是 "waiting to be processed." 的确切含义 例如,假设我有一个执行者,我对一些 Runnable
对象调用 execute()
(假设所有这些对象都有效地忽略了中断)。我知道如果我现在调用 shutdown
,所有这些对象都将完成执行,无论如何。
但是,如果我此时调用shutdownNow
,会不会和调用shutdown
有同样的效果?还是有些对象没有执行?换句话说,如果我希望执行程序尽快退出,我最好的选择是始终调用 shutdownNow()
,即使传递给执行程序的 Runnables
都有效地忽略了中断吗?
What I would like to clarify is the exact meaning of "waiting to be processed".
表示run()
方法还没有被执行者调用过的所有任务
If I call shutdownNow at this point, will it have the same effect as calling shutdown?
没有
Or is it possible that some of the objects will not be executed?
没错。
In other words, if I want an executor to exit as fast as possible, is my best option always to call shutdownNow(), even when the Runnables passed to the executor all effectively ignore interruptions?
没错。
更好的是,重新编写 Runnables 以注意中断......或者在关机时设置超时......
API for shutdownNow
方法说:
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt(), so any task that fails to respond to
interrupts may never terminate.
假设您有一个很棒的 Runnable
,它在启动后 10 秒内不会被打断:
Runnable r = new Runnable() {
@Override
public void run() {
long endAt = System.currentTimeMillis() + 10000;
while (System.currentTimeMillis() < endAt);
}
};
你有一个只有 1 个线程的执行器,你安排了 运行nable 10 次:
ExecutorService executor = Executors.newFixedThreadPool(1);
for (int i = 0; i < 10; i++)
executor.execute(r);
现在您决定调用 shutdown
:
- 执行程序将继续执行完整的 10 x 10 秒,并且将执行计划的所有内容。这些任务看不到您正在关闭他们的执行者。
shutdown
如果你想要一个 "short lived" 执行器来完成一些任务,可以使用 shutdown
。您可以立即调用 shutdown
,它稍后会被清理。
或者shutdownNow()
:
- 需要 10 秒。已经 运行ning 的任务试图被中断,但这显然没有效果,所以它继续 运行。仍在队列中等待的其他 9 个任务是 "cancelled" 并作为 List 返回给您,因此您可以对它们做一些事情,比如稍后安排它们。如果第一个任务尚未开始,也可能需要 0 秒。你会得到所有的任务。只要您想中止整个执行程序,就会使用该方法。
根据 documentation,当 shutdown()
被调用时,任何已经提交的任务(我假设通过 submit()
或 execute
)将被执行。当调用 shutdownNow()
时,执行器将暂停所有等待处理的任务,并尝试停止正在执行的任务。
我想澄清的是 "waiting to be processed." 的确切含义 例如,假设我有一个执行者,我对一些 Runnable
对象调用 execute()
(假设所有这些对象都有效地忽略了中断)。我知道如果我现在调用 shutdown
,所有这些对象都将完成执行,无论如何。
但是,如果我此时调用shutdownNow
,会不会和调用shutdown
有同样的效果?还是有些对象没有执行?换句话说,如果我希望执行程序尽快退出,我最好的选择是始终调用 shutdownNow()
,即使传递给执行程序的 Runnables
都有效地忽略了中断吗?
What I would like to clarify is the exact meaning of "waiting to be processed".
表示run()
方法还没有被执行者调用过的所有任务
If I call shutdownNow at this point, will it have the same effect as calling shutdown?
没有
Or is it possible that some of the objects will not be executed?
没错。
In other words, if I want an executor to exit as fast as possible, is my best option always to call shutdownNow(), even when the Runnables passed to the executor all effectively ignore interruptions?
没错。
更好的是,重新编写 Runnables 以注意中断......或者在关机时设置超时......
API for shutdownNow
方法说:
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
假设您有一个很棒的 Runnable
,它在启动后 10 秒内不会被打断:
Runnable r = new Runnable() {
@Override
public void run() {
long endAt = System.currentTimeMillis() + 10000;
while (System.currentTimeMillis() < endAt);
}
};
你有一个只有 1 个线程的执行器,你安排了 运行nable 10 次:
ExecutorService executor = Executors.newFixedThreadPool(1);
for (int i = 0; i < 10; i++)
executor.execute(r);
现在您决定调用 shutdown
:
- 执行程序将继续执行完整的 10 x 10 秒,并且将执行计划的所有内容。这些任务看不到您正在关闭他们的执行者。
shutdown
如果你想要一个 "short lived" 执行器来完成一些任务,可以使用shutdown
。您可以立即调用shutdown
,它稍后会被清理。
或者shutdownNow()
:
- 需要 10 秒。已经 运行ning 的任务试图被中断,但这显然没有效果,所以它继续 运行。仍在队列中等待的其他 9 个任务是 "cancelled" 并作为 List 返回给您,因此您可以对它们做一些事情,比如稍后安排它们。如果第一个任务尚未开始,也可能需要 0 秒。你会得到所有的任务。只要您想中止整个执行程序,就会使用该方法。