我终于会写 Java 的定时任务了!( 二 )

从上面的抽象方法可以看到,第一个参数是 Runnable 接口或 Callable 接口,这里就是写任务逻辑的,后面的 delay 也和之前的意思一样,延迟多少时间才开始执行这个定时任务,unit 主要是指定 long 参数的时间单位 。period 也是一样的意思 , 间隔多少秒(周期)才执行下一次的任务 。

ExecutorService 接口表述了异步执行的机制,并且可以让任务在后台执行 。ExecutorService 接口的实现类有我们知道的 ThreadPoolExecutor (不知道的话,现在就知道啦) 。
基本使用那我们如何获取 ScheduledExecutorService 的实现类?如何使用它实现定时任务?
可以通过 Executors.newSingleThreadScheduledExecutor() 获取其实现类,然后调用 schedule() 方法实现定时任务 。
现在先看一下,如何使用:
@Slf4jpublic class ScheduledExecutorServiceDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {testScheduledExecutorService();}public static void testScheduledExecutorService() throws ExecutionException, InterruptedException {ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();log.info("2秒后开始执行任务 , 此刻时间---{}", LocalDateTime.now());ScheduledFuture<?> future = scheduledExecutorService.schedule(() -> {log.info("任务开始---{}", LocalDateTime.now());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}log.info("任务结束---{}", LocalDateTime.now());return "ok";}, 2000, TimeUnit.MILLISECONDS); // 延迟 2 秒后执行log.info("任务执行后 future {}, 时间 {}", future.get(), LocalDateTime.now());}}控制台输出:
14:15:44.510 [main] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 2秒后开始执行任务,此刻时间---2022-10-25T14:15:44.50914:15:46.524 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务开始---2022-10-25T14:15:46.52414:15:48.537 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务结束---2022-10-25T14:15:48.53714:15:48.538 [main] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务执行后 future ok, 时间 2022-10-25T14:15:48.538很明显 , 这里不是一个定时任务,因为只执行了一次就结束了,所以我们需要调用两外两个来实现 , 分别是 scheduleAtFixedRate() 方法和 scheduleWithFixedDelay() 方法 。
固定频率触发定时任务scheduleAtFixedRate() 方法,可以固定多久就触发一次任务 。下面我们写一个延迟 2 秒后开始执行任务,经过 5 秒后再执行下一次的任务的代码:
@Slf4jpublic class ScheduledExecutorServiceDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {testFixedRate();}public static void testFixedRate() {ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();log.info("2秒后开始执行任务,此刻时间---{}", LocalDateTime.now());// 固定频率(每隔5秒)开始执行一个任务scheduledExecutorService.scheduleAtFixedRate(() -> {log.info("任务开始---{}", LocalDateTime.now());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}log.info("任务结束---{}", LocalDateTime.now());}, 2000, 5000, TimeUnit.MILLISECONDS);}}通过 Thread.sleep(2000) 模拟任务执行了 2 秒的时间 , 控制台输出如下:
14:17:15.081 [main] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 2秒后开始执行任务,此刻时间---2022-10-25T14:17:15.07914:17:17.094 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务开始---2022-10-25T14:17:17.09414:17:19.109 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务结束---2022-10-25T14:17:19.10914:17:22.094 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务开始---2022-10-25T14:17:22.09414:17:24.106 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务结束---2022-10-25T14:17:24.10614:17:27.090 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务开始---2022-10-25T14:17:27.09014:17:29.099 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务结束---2022-10-25T14:17:29.099可以看到,第一次执行的时间是 14:17:17  , 即第 17 秒,下一次执行的时间是 14:17:22,即第 22 秒,这个过程经过了 5 秒钟,这就是 scheduleAtFixedRate() 方法的效果 。
固定延迟触发定时任务scheduleWithFixedDelay() 方法,可以固定任务完成后延迟多久才执行下一次任务 。下面我们写一个延迟 1 秒后开始执行定时任务,当任务完成后,延迟 4 秒再执行下一次任务 。代码如下:

推荐阅读