另一种类型的任务池是计划任务池。从名称来看,我们可以假设我们使用此类型来安排何时应启动特定任务。

当我们有一个任务要在一段时间后启动一个活动,或者我们想要安排一个重复性任务时,这种类型的服务很有用。

要使用一个,我们调用Executors.newScheduledThreadPool(1)

稍后我们将讨论参数。但现在,我们需要知道的是,当调用此方法时,我们将获得一个ScheduledExecutorService对象。

ScheduledExecutorService是一个扩展ExecutorService的接口。

该界面中出现以下方法:

方法 解释

ScheduledFuture<?>
schedule(Runnable command,
                                  long delay, TimeUnit unit);
创建并执行在指定延迟后运行的一次性操作。

<V> ScheduledFuture<V>
schedule(Callable<V> callable,
                                      long delay, TimeUnit unit);
创建并执行一个预定的未来在指定延迟后执行的对象。

ScheduledFuture<?>
scheduleAtFixedRate(Runnable command,
                                             long initialDelay,
                                             long period,
                                             TimeUnit unit);
创建并执行一个循环操作,该操作首先在指定的初始延迟后运行,然后在指定的时间段后再次运行。换句话说,执行将在initialDelay之后开始,然后是initialDelay + period,然后是initialDelay + 2 * period,依此类推。

ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                long initialDelay,
                                                long delay,
                                                TimeUnit unit);
创建并执行一个循环操作,该操作在指定的初始延迟后首先执行,然后在一次执行完成和下一次执行开始之间以指定的延迟再次执行。

因此,该界面让我们可以定期或在一定延迟后运行任务。

有关 newScheduledThreadPool 方法的更多信息。

我们可以通过多种方式调用它:


newScheduledThreadPool(int corePoolSize)
corePoolSize是保留在池中的线​​程数,即使它们是空闲的。

newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)

corePoolSize是保留在池中的线​​程数,即使它们是空闲的。

threadFactory是创建新线程时使用的工厂。

这两种方法都将创建一个线程池,该线程池可以安排在指定延迟后或定期执行的操作。

让我们看一个例子来了解ScheduledThreadPool是如何工作的。

例如,假设我们有一项任务是每 5 秒检查一次电子邮件,但这种检查不能影响主程序并且可能会消耗额外的资源。

我们有一个模拟检查电子邮件的任务类。


public class Task implements Runnable {
   @Override
   public void run() {
       System.out.println("Checking email...");
   }
}

接下来,我们创建一个线程池并安排检查。


ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
executorService.scheduleAtFixedRate(new Task(), 0, 5, TimeUnit.SECONDS);

在输出中,我们每 5 秒就会看到:

正在检查电子邮件...

通常,我们可以使用这样的池来执行周期性的“内务处理”任务,如示例中所示。管家任务是无论主程序在做什么都必须执行的任务。