另一种类型的任务池是计划任务池。从名称来看,我们可以假设我们使用此类型来安排何时应启动特定任务。
当我们有一个任务要在一段时间后启动一个活动,或者我们想要安排一个重复性任务时,这种类型的服务很有用。
要使用一个,我们调用Executors.newScheduledThreadPool(1)。
稍后我们将讨论参数。但现在,我们需要知道的是,当调用此方法时,我们将获得一个ScheduledExecutorService对象。
ScheduledExecutorService是一个扩展ExecutorService的接口。
该界面中出现以下方法:
方法 | 解释 |
---|---|
|
创建并执行在指定延迟后运行的一次性操作。 |
|
创建并执行一个预定的未来在指定延迟后执行的对象。 |
|
创建并执行一个循环操作,该操作首先在指定的初始延迟后运行,然后在指定的时间段后再次运行。换句话说,执行将在initialDelay之后开始,然后是initialDelay + period,然后是initialDelay + 2 * period,依此类推。 |
|
创建并执行一个循环操作,该操作在指定的初始延迟后首先执行,然后在一次执行完成和下一次执行开始之间以指定的延迟再次执行。 |
因此,该界面让我们可以定期或在一定延迟后运行任务。
有关 newScheduledThreadPool 方法的更多信息。
我们可以通过多种方式调用它:
|
corePoolSize是保留在池中的线程数,即使它们是空闲的。 |
|
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 秒就会看到:
正在检查电子邮件...
通常,我们可以使用这样的池来执行周期性的“内务处理”任务,如示例中所示。管家任务是无论主程序在做什么都必须执行的任务。
GO TO FULL VERSION