执行器服务:它如何充当线程池的看门狗?



我想了解ExecutorService如何充当它创建的线程池的看门狗。

基本上,据我了解,ExecutorService只是一个对象,它不是创建其他线程的"线程或进程"。

通常,对于ThreadPoolExecutor

threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
// Now, requesting Executor Service to "execute" each submitted Tasks.
threadPoolExecutor.execute(runnable);

ScheduleThreadPoolExecutor也是如此

scheduledThreadPool = Executors.newSingleThreadScheduledExecutor(threadFactory);
scheduledThreadPool.scheduleAtFixedRate(runnable, 2000, 3000, TimeUnit.MILLISECONDS);

从本质上讲,它们只是对象,它们如何能够 ,例如,"如果线程死亡,则重新启动线程"。

我无法理解这一点,例如,在ScheduledThreadPoolExecutor的情况下,我们调用方法一次进行定期操作,之后,该对象如何能够管理线程。

我确实研究了代码,我仍然怀疑对象如何管理所有这些?(创建线程池、将作业提交到队列、重新启动线程池中的线程等(

你应该最好看看代码。实际上,大多数执行器都有一个私有嵌套类,它封装了您的Runnable并将其管理在线程中。

Executors.newSingleThreadScheduledExecutor 只需创建一个带有一个线程的ScheduledThreadPoolExecutor然后,当您推送任务时,它会创建一个ScheduledFutureTask(也封装在RunnableScheduledFuture中(,并在必要时创建一个线程。

固定费率时间表 :

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit) {
...
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Object>(command,
null,
triggerTime,
unit.toNanos(period)));
delayedExecute(t);
return t;
}

延迟执行

private void delayedExecute(Runnable command) {
if (isShutdown()) { // handling the cancellation 
reject(command);
return;
}
if (getPoolSize() < getCorePoolSize()) // increase number of thread if necessary
prestartCoreThread();
super.getQueue().add(command); // queue the task to be processed a soon as a task is finished
}

排队后,执行器将逐个取消排队(在单线程执行器的情况下,一个线程的线程池(,最终会创建一个线程,在代码中也称为worker。它将调用之前排队的任务的 run(( 方法:

ScheduledFutureTask.run

public void run() {
if (isPeriodic())
runPeriodic();
else
ScheduledFutureTask.super.run(); // just call run() of your Runnable
}

假设我们之前使用scheduleAtFixedRate提交了一个任务,该任务将被视为周期性任务,并且方法runPeriodic 将调用:

ScheduledFutureTask.runPeriodic

private void runPeriodic() {
boolean ok = ScheduledFutureTask.super.runAndReset(); // call run() from your Runnable
boolean down = isShutdown();
// Reschedule if not cancelled and not shutdown or policy allows
if (ok && (!down ||
(getContinueExistingPeriodicTasksAfterShutdownPolicy() && !isTerminating()))) {
long p = period;
if (p > 0)
time += p;
else
time = now() - p;
ScheduledThreadPoolExecutor.super.getQueue().add((Runnable) this);
}
// This might have been the final executed delayed
// task.  Wake up threads to check.
else if (down)
interruptIdleWorkers();
}

这让你对魔术是如何发生的有一个想法。大多数"看门狗"的工作都发生在线程内部,他们自己管理。执行器的工作是确保它的队列始终为空,并通过线程调度和创建任务。 然后,任务的行为通过直接访问执行器由自己处理,这要归功于Java的嵌套类可能性。

最新更新