Java代码规范之使用ScheduledExecutorService代替Timer进行定时任务并行处理
目录
该条规范是什么
该规范指出在Java编程中,当需要多线程并行处理定时任务时,应使用ScheduledExecutorService
代替Timer
。因为当Timer
运行多个TimerTask
时,只要其中一个TimerTask
没有捕获抛出的异常,其他任务便会自动终止运行,而使用ScheduledExecutorService
则没有这个问题。
为什么这么规定
以下是该规范的原因:
- 异常终止问题:使用
Timer
运行多个TimerTask
时,如果其中一个TimerTask
没有捕获抛出的异常,其他任务会自动终止运行,可能导致未预期的结果和不一致的状态。 - 解决异常终止问题:使用
ScheduledExecutorService
可以解决Timer
的异常终止问题,它能够更好地处理异常并继续执行其他任务,避免了任务的中断和不一致。
ScheduledExecutorService 原理和示例
原理
ScheduledExecutorService 是 Java 中的一个接口,它是 ExecutorService 的子接口,用于在给定的延迟时间后或定期执行任务。ScheduledExecutorService 基于线程池的原理,可以创建和管理多个线程来执行任务。
ScheduledExecutorService 提供了几种调度任务的方法,包括:
schedule(Runnable command, long delay, TimeUnit unit)
:在给定的延迟时间后执行任务。scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
:在给定的初始延迟时间后开始执行任务,并按固定的时间间隔重复执行。scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
:在给定的初始延迟时间后开始执行任务,并在每次任务结束后等待指定的时间间隔,然后再次执行。
ScheduledExecutorService 可以通过 Executors 工具类的静态方法进行创建。
示例
下面是一个使用 ScheduledExecutorService 的示例代码:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Example {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () -> System.out.println("Task executed.");
// 在延迟 2 秒后执行任务
executor.schedule(task, 2, TimeUnit.SECONDS);
// 在延迟 1 秒后开始执行任务,并每隔 3 秒重复执行
executor.scheduleAtFixedRate(task, 1, 3, TimeUnit.SECONDS);
// 在延迟 1 秒后开始执行任务,并在每次任务结束后等待 2 秒,然后再次执行
executor.scheduleWithFixedDelay(task, 1, 2, TimeUnit.SECONDS);
// 主线程等待一段时间后关闭 ScheduledExecutorService
Thread.sleep(10_000);
executor.shutdown();
}
}
在上述示例中,首先创建了一个 ScheduledExecutorService 对象,使用 Executors.newScheduledThreadPool 方法创建了一个具有单个线程的线程池。然后定义了一个简单的任务(Runnable),并通过 schedule、scheduleAtFixedRate 和 scheduleWithFixedDelay 方法分别安排了任务的执行。
运行示例代码会输出类似以下内容:
Task executed.
Task executed.
Task executed.
Task executed.
...
可以看到,任务按照指定的延迟时间和时间间隔被定时执行。
这个示例展示了 ScheduledExecutorService 的典型使用方式,通过调度方法可以在给定的延迟时间后或定期执行任务,从而实现定时任务的功能。