谈谈在 Java 中实现定时任务的几种方式

本文探讨了在Java中实现定时任务的多种方法,包括Spring的@schedule注解、JDK的Timer & TimerTask、开源调度框架Quartz以及线程池ScheduleExecutorService和ScheduledThreadPoolExecutor。着重介绍了@schedule的使用及其内部基于Quartz的实现原理,同时分析了TimerTask的限制,以及Quartz的特性和核心元素。
摘要由CSDN通过智能技术生成

工作中经常接触到定时任务,实现定时任务的方式很多,常见的有 Spring @schedule 注解配合 Cron 表达式、JDK 自带的 TimerTask or Timer、使用开源作业调度框架 Quartz、线程池 ScheduleExecutorService 和其实现类 ScheduledThreadPoolExecutor。

@schedule 注解

Spring 中的 @schedule 是我最早接触学会的,注解实现非常方便,注解中有三个参数分别是 Cron 表达式、fixedRate 和 initialDelay,具体使用看你的场景,需要注意的是使用 @schedule 注解的方法的类必须用 @Component (最好)或者 @Service @Controller 等注解进行修饰,将其交给 Spring 进行托管,且在 XML 配置文件中必须有相应的配置。随着学习的深入,后来了解到 @schedule 内部本质上是基于 Quartz 实现的。Quartz 是一个任务调度框架,@schedule 注解修饰的方法会被交给 ScheduledAnnotationBeanPostProcessor 处理,在 ScheduledAnnotationBeanPostProcessor 类中会解析 @schedule 中的三个参数,根据参数的不同,将任务交给 ScheduledTaskRegistrar 进行处理,3种不同属性的task均由quartz的taskScheduler的不同方法来完成,scheduleWithFixedDelay、
scheduleAtFixedRate 和 schedule。

Timer & TimerTask

Timer 是 JDK 中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。TimerTask 是一个实现了 Runnable 接口的抽象类,代表一个可以被 Timer 执行的任务。我们可以这样理解 Timer 是一种定时器工具,用来在一个后台线程计划执行指定任务,而 TimerTask 是一个抽象类,它的子类代表一个可以被 Timer 计划的任务。

TimerTask 我自己极少使用,主要是它有一些弊端,Timer 在执行定时任务时只会创建一个线程,所以如果存在多个任务,且任务时间过长,超过了两个任务的间隔时间,那么第二个任务只能等待第一个任务执行完毕后再执行,其行为可能已经不符合编码者期望的了。例如 t2 定义 3s 后开始执行,t1 定义在 1s 后执行,但是 t1 执行过程总共消耗了 4s,那么实际上 t2 会在第 6s 才会执行,因为 Timer 是单线程的缘故。

package com.zhy.concurrency.Timer;
import java.util.Timer;
import java.util.TimerTask;

public class TimerTest
{
   
    private static long start;
    public static void main(String[] args) throws Exception{
        TimerTask task1 = new TimerTask(){
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值