Java定时器怎么实现?Timer和线程池方法全攻略

 更新时间:2026年07月14日 09:19:08   作者:沐雨橙风ιε  
还在为Java定时任务发愁吗?本文详细介绍了四种常用方法:Timer、ScheduledExecutorService线程池、Spring Task和Quartz框架,从基础用法到高级配置,手把手教你实现定时任务,并附有代码示例,助你轻松应对各种定时场景

Java实现定时器的方法有很多,这篇文章主要介绍一下博主知道的几种方法。 

方法一、使用Timer

1、Timer和TimerTask是java.util包下的类,用于实现定时任务

  • 第一步:创建TimerTask定时器任务
  • 第二步:创建Timer定时器,调用定时器的方法执行定时器任务

TimerTask是Runnable接口的实现类,Runnable接口的实例通常称为任务。

2、Timer中有两个执行定时任务方法

  • schedule()
  • scheduleAtFixedRate() 

schedule()

void schedule(TimerTask task, Date time)

在时间time执行一次任务(如果指定的事件已经过去了,则马上执行)。

void schedule(TimerTask task, long delay)

在指定时间后执行1次任务(其中delay表示时延,单位是毫秒)。

void schedule(TimerTask task, long delay, long period) 

在指定时间后周期性地执行任务(在delay毫秒后,每period毫秒执行一次任务)。

public void schedule(TimerTask task, Date firstTime, long period)

在指定时间后周期性地执行任务(从指定的事件firstTime开始,每period毫秒执行一次任务)。

scheduleAtFixedRate()

void scheduleAtFixedRate(TimerTask task, long delay, long period)

在指定延迟时间后周期性地执行任务(delay毫秒后,每period毫秒执行一次)。

void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)

从指定的日期firstTime开始,每period毫秒执行一次任务。

3、案例代码

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
public class TimerExample {

    public static void main(String[] args) {
        // 创建定时器
        Timer timer = new Timer();

        // 创建定时器任务
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Hello world!");
            }
        };

        timer.schedule(task, new Date()); // 马上执行一次
        timer.schedule(task, 1000); // 1秒后执行一次
        timer.schedule(task, new Date(), 2000); // 每2秒执行一次
        timer.schedule(task, 2000, 2000); // 2秒后每2秒执行一次

        timer.scheduleAtFixedRate(task, 3000, 3000); // 3秒后每3秒执行一次
        timer.scheduleAtFixedRate(task, new Date(), 4000); // 每3秒执行一次
    }

}

方法二、使用线程池

Java线程池的相关API中有一个类叫做ScheduledExecutorService,专门用于执行定时任务。

 其中有几个方法用于执行定时任务:

  • schedule()
  • scheduleAtFixedRate() 
  • scheduleWithFixedDelay()

TimeUnit是一个枚举类,用于指定时间单位:

  • NANOSECONDS:纳秒
  • MICROSECONDS:微秒
  • MILISECONDS:毫秒
  • SECONDS:秒
  • MINUTE:分钟
  • HOURS:小时
  • DAYS:天

ScheduledExecutorService的方法跟Timer有点细微的区别:有返回值。

  • 所有方法的返回值类型都是java.util.concurrent.ScheduledFuture。

schedule()

public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)

在指定时间后执行1次任务,其中delay表示时延,单位是TimeUnit指定的时间单位。

public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)

在指定delay个时间单位后执行1次任务,其中delay表示时延。

scheduleAtFixedRate()

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

在指定延迟时间后周期性地执行任务(在initialDelay个时间单位后,每period个时间单位执行一次)。

scheduleWithFixedDelay()

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

在指定延迟时间后周期性地执行任务(在initialDelay个时间单位后,每period个时间单位执行一次)。

案例代码

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
public class ScheduledExecutorServiceExample {

    public static void main(String[] args) {
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello world!");
            }
        };

        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);

        scheduledThreadPool.schedule(task, 3, TimeUnit.SECONDS);// 3秒后执行一次任务
        scheduledThreadPool.schedule(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                return null;
            }
        }, 3, TimeUnit.SECONDS); // 3秒后执行一次任务

        scheduledThreadPool.scheduleAtFixedRate(task, 3, 3, TimeUnit.SECONDS); // 3秒后,每3秒执行一次任务
        scheduledThreadPool.scheduleWithFixedDelay(task, 3, 3, TimeUnit.SECONDS); // 3秒后,每3秒执行一次任务
    }

}

方法三、使用Spring Task

第一步:在springBoot启动类上添加@EnableScheduling注解

package cn.edu.sgu.www;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@EnableScheduling
@SpringBootApplication
public class TimerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TimerApplication.class, args);
    }

}

第二步:创建一个定时任务组件

在类的方法上使用@Schedule注解,通过注解的cron属性设置定时器的属性。

package cn.edu.sgu.www.timer;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Component
public class TimerTask {

    /**
     * cron属性指定在每年的7月18日12:55:00执行一次定时任务
     * 对cron表达式感兴趣的可以去学习了解一下
     */
    @Scheduled(cron = "0 55 12 18 7 *")
    public void task() {
        System.out.println("执行定时任务...");
    }

}

时间到了之后,控制台输出了一次。 

方法四、使用Quartz任务调度框架

第一步:在pom.xml中添加quartz的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

第二步:创建定时任务 

package cn.edu.sgu.www.timer;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Component
public class QuartzJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        System.out.println("执行QuartzJob定时任务...");
    }

}

第三步:配置定时任务触发条件

package cn.edu.sgu.www.config;

import cn.edu.sgu.www.timer.QuartzJob;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail jobDetail() {
        return JobBuilder.newJob(QuartzJob.class)   // 绑定要执行的任务类
                .withIdentity("quartzJob")          // 设置任务名称
                .storeDurably()                     // 信息持久化
                .build();
    }

    @Bean
    public Trigger trigger(JobDetail jobDetail) {
        // 定义Cron表达式,每10秒触发一次
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?");

        return TriggerBuilder.newTrigger()
                .forJob(jobDetail)                   // 绑定JobDetail对象
                .withIdentity("trigger")             // 定义触发器名称
                .withSchedule(cronScheduleBuilder)   // 绑定Cron表达式
                .build();
    }

}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java 实战范例之员工管理系统的实现

    Java 实战范例之员工管理系统的实现

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+vue+Springboot+ssm+mysql+maven+redis实现一个前后端分离的员工管理系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • 一篇看懂Java中的Unsafe类

    一篇看懂Java中的Unsafe类

    在阅读AtomicInteger的源码时,看到了这个类:sum.msic.Unsafe,之前从没见过。所以花了点时间研究了下,下面这篇文章主要给大家介绍了关于Java中Unsafe类的相关资料,需要的朋友可以参考借鉴,下面来一起学习学习吧
    2018-05-05
  • SpringBoot启动过程与自动配置过程解读

    SpringBoot启动过程与自动配置过程解读

    本文详解SpringBoot启动流程及自动配置机制,涵盖main方法初始化、环境配置、容器启动等关键步骤,解析条件注解与spring.factories的智能配置逻辑,并提供自定义配置方法,强调其"约定优于配置"的核心理念与工程化封装特性
    2025-08-08
  • SpringBoot jackson 精度处理问题解决

    SpringBoot jackson 精度处理问题解决

    由于JavaScript处理的最大数值限制,较大的雪花ID在JS中容易溢出,为解决此问题,可在SpringMVC或SpringBoot中使用@RequestBody注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10
  • 使用Spring底层组件实现Aware接口

    使用Spring底层组件实现Aware接口

    这篇文章主要介绍了使用Spring底层组件实现Aware接口,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Spring Retry重试框架的使用讲解

    Spring Retry重试框架的使用讲解

    重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次。用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有,感兴趣的可以了解一下
    2022-10-10
  • Java四种元注解介绍

    Java四种元注解介绍

    元注解是用来修饰注解的注解,在java.lang.annotation包下,当我们需要自己定义一个注解去做某些事情的时候,我们要对该注解进行一些限制,确保我们注解的作用域,这篇文章主要介绍了Java四种元注解介绍,需要的朋友可以参考下
    2024-08-08
  • Java多线程之多线程异常捕捉

    Java多线程之多线程异常捕捉

    在java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked exception处理掉,通过此篇文章给大家分享Java多线程之多线程异常捕捉,需要的朋友可以参考下
    2015-08-08
  • Swagger使用和注释详解

    Swagger使用和注释详解

    Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务,这篇文章主要介绍了Swagger使用和注释介绍,需要的朋友可以参考下
    2024-05-05
  • java字符串拼接与性能分析详解

    java字符串拼接与性能分析详解

    在JAVA中拼接两个字符串的最简便的方式就是使用操作符”+”。如果你用”+”来连接固定长度的字符串,可能性能上会稍受影响,但是如果你是在循环中来”+”多个串的话,性能将指数倍的下降,下面我们分析一下JAVA字符串拼接的性能
    2014-01-01

最新评论