@Slf4jpublic class ScheduledExecutorServiceDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {testFixedDelay();}public static void testFixedDelay() {ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();log.info("1秒后开始执行任务,此刻时间---{}", LocalDateTime.now());// 任务完成后间隔4秒开始执行下一次任务scheduledExecutorService.scheduleWithFixedDelay(() -> {log.info("任务开始---{}", LocalDateTime.now());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}log.info("任务结束---{}", LocalDateTime.now());}, 1000, 4000, TimeUnit.MILLISECONDS);}}
通过 Thread.sleep(2000)
模拟任务执行了 2 秒的时间 , 控制台输出如下:
14:20:31.352 [main] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 1秒后开始执行任务,此刻时间---2022-10-25T14:20:31.35114:20:32.370 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务开始---2022-10-25T14:20:32.37014:20:34.371 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务结束---2022-10-25T14:20:34.37114:20:38.379 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务开始---2022-10-25T14:20:38.37914:20:40.381 [pool-1-thread-1] INFO cn.god23bin.demo.timer.ScheduledExecutorServiceDemo - 任务结束---2022-10-25T14:20:40.381
可以看到,第一次任务结束的时间是 14:20:34
,即第 34 秒,下一次执行的时间是 14:17:38
,即第 38 秒,这个过程经过了 4 秒钟,这就是 scheduleWithFixedDelay() 方法的效果 。
以上就是 ScheduledExecutorService 实现的定时任务,接下来看看 Spring 提供的 。
Spring 提供的定时任务Spring 提供了 @EnableScheduling
和 @Scheduled
这两个注解来实现定时任务 。
我们可以编写一个类,加上 @Component
让 Spring 来管理这个 Bean(当然,也可以用 @Configuration 注解),加上 @EnableScheduling
表明该 Bean 具有可开启定时任务的功能 。
在这个普通的类中编写方法,你可以让你写的方法成为一个定时任务,只需在方法上加上 @Scheduled
注解就可以了,就是这么简单!
还有一个就是 cron 表达式 需要学习,这个表达式可以表明这个方法何时执行 。
下面是一个简单的定时任务:
@Slf4j@Component@EnableSchedulingpublic class TaskDemo {@Scheduled(cron = "*/1 * * * * ?")public void printTime() throws InterruptedException {log.info("此刻时间 {}", LocalDateTime.now());}}
cron 表达式有 6 位,是必须的,从左到右分别表示:秒、分、时、日、月、周
。
当然也有可能是 7 位,那么最后一位就是年(一般省略不写):秒、分、时、日、月、周、年
。
取值说明:正常认识,秒分都是 0 - 59 , 时则是 0 - 23,日则是 1 - 31,月则是 1-12,周则是 1 - 7 。年则只有 1970 - 2099
每一位都可以用数字表示 , 当然还可以用一些特殊字符表示 , 比如上面出现的 */1 * * * * ?
, 第 1 位的 */1
表示任意秒每隔1秒 , 第 2 位的 *
表示任意分钟 , 以此类推 。
详细可参考这里:简书-Cron表达式的详细用法上面的代码运行之后,控制台输出:
Cron 生成工具:https://cron.qqe2.com/
2022-10-25 14:26:22.013INFO 18304 --- [scheduling-1] cn.god23bin.demo.task.TaskDemo: 此刻时间 2022-10-25T14:26:22.0132022-10-25 14:26:23.010INFO 18304 --- [scheduling-1] cn.god23bin.demo.task.TaskDemo: 此刻时间 2022-10-25T14:26:23.0102022-10-25 14:26:24.011INFO 18304 --- [scheduling-1] cn.god23bin.demo.task.TaskDemo: 此刻时间 2022-10-25T14:26:24.0112022-10-25 14:26:25.011INFO 18304 --- [scheduling-1] cn.god23bin.demo.task.TaskDemo: 此刻时间 2022-10-25T14:26:25.011
可以看到,确实是每隔 1 秒执行一次 printTime()
这个定时任务 。@Scheduled 的另外两个属性
@Scheduled
注解除了 cron
这个属性外,还有 fixedRate
属性和 fixedDelay
属性,同理,就是固定频率触发定时任务和固定延迟触发定时任务fixedRate
@Slf4j@Component@EnableSchedulingpublic class TaskDemo {/*** 当前任务执行到下一个任务开始的时间(固定频率开始执行一个任务,每5秒执行),都是单线程处理的**/@Scheduled(fixedRate = 5000)public void printTime1() throws InterruptedException {log.info("任务开始------- {}", LocalDateTime.now());Thread.sleep(1000);log.info("任务完成------- {}", LocalDateTime.now());}}
推荐阅读
- realme真我v15什么时候发布_realme锦鲤手机发布时间
- 真我GTNeo2T测评_真我GTNeo2T续航情况测试
- 闻道Go语言,6月龄必知必会
- 我的世界驯服马方法是什么
- Paxos分布式系统共识算法?我愿称其为点歌算法…
- C#实现生成Markdown文档目录树
- 我的世界怎么制作垂直升降电梯(我的世界怎么做垂直升降电梯)
- 我的世界1.12水电梯怎么做(我的世界1.16版本水电梯如何做)
- 如何在我的世界做电梯(网易版mc怎么做电梯)
- 我的世界脚手架电梯怎么做(我的世界建筑电梯怎么做)