Java案例如何实现定时任务?

wen python案例 1

本文目录导读:

Java案例如何实现定时任务?

  1. 基础方案:使用 java.util.Timer
  2. 企业级方案:ScheduledExecutorService(推荐)
  3. Spring Boot集成 Quartz(最强大,支持Cron)
  4. Spring Boot @Scheduled 注解(简单实用,推荐)
  5. 分布式场景:Redis + Redisson的分布式调度
  6. 选择建议

在Java中实现定时任务有多种方式,从简单到复杂,根据你的需求场景选择合适的方法,以下是几种主流的实现方案:

基础方案:使用 java.util.Timer

适合简单的单次或固定周期任务,不需要复杂调度。

import java.util.Timer;
import java.util.TimerTask;
public class TimerExample {
    public static void main(String[] args) {
        Timer timer = new Timer("MyTimer");
        // 延迟1秒后执行,然后每3秒执行一次
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("任务执行中..." + System.currentTimeMillis());
            }
        }, 1000, 3000);
        // 如果需要停止任务
        // timer.cancel();
    }
}

缺点:所有任务共用一个线程,一个任务异常会影响其他任务;不支持cron表达式。

企业级方案:ScheduledExecutorService(推荐)

从Java 5开始引入,基于线程池,性能更好,更稳定。

import java.util.concurrent.*;
public class ScheduledExecutorExample {
    public static void main(String[] args) throws InterruptedException {
        // 创建线程池,核心线程数2
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
        // 一次性任务:延迟5秒执行
        scheduler.schedule(() -> {
            System.out.println("一次性任务执行:" + System.currentTimeMillis());
        }, 5, TimeUnit.SECONDS);
        // 固定延迟任务:上次执行完后延迟3秒再执行
        scheduler.scheduleWithFixedDelay(() -> {
            System.out.println("固定延迟任务:" + System.currentTimeMillis());
            try {
                Thread.sleep(2000); // 模拟任务执行耗时
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }, 0, 3, TimeUnit.SECONDS);
        // 固定频率任务:每2秒执行一次,不受任务耗时影响
        scheduler.scheduleAtFixedRate(() -> {
            System.out.println("固定频率任务:" + System.currentTimeMillis());
        }, 0, 2, TimeUnit.SECONDS);
        // 让主线程运行一段时间再关闭
        Thread.sleep(15000);
        scheduler.shutdown();
    }
}

优点:基于线程池,支持多任务并行;异常处理更灵活;适合生产环境。

Spring Boot集成 Quartz(最强大,支持Cron)

适合复杂的定时任务调度,如“每天上午10点执行”等。

添加依赖(pom.xml)

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

创建任务类

import org.quartz.Job;
import org.quartz.JobExecutionContext;
public class MyQuartzJob implements Job {
    @Override
    public void execute(JobExecutionContext context) {
        System.out.println("Quartz任务执行:" + System.currentTimeMillis());
        // 业务逻辑代码
    }
}

配置调度器

import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail myJobDetail() {
        return JobBuilder.newJob(MyQuartzJob.class)
                .withIdentity("myJob", "group1")
                .storeDurably()
                .build();
    }
    @Bean
    public Trigger myTrigger() {
        // Cron表达式:每天上午10:15执行
        // 格式: 秒 分 时 日 月 周 [年]
        String cronExpression = "0 15 10 * * ?";
        return TriggerBuilder.newTrigger()
                .forJob(myJobDetail())
                .withIdentity("myTrigger", "group1")
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                .build();
    }
}

本机测试用的Cron示例

// 每5秒执行一次
"*/5 * * * * ?"
// 每天中午12点整执行
"0 0 12 * * ?"
// 每周一至周五上午10:30执行
"0 30 10 ? * MON-FRI"

Spring Boot @Scheduled 注解(简单实用,推荐)

适合轻量级应用,Spring Boot原生支持,无需额外依赖。

启用定时任务

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling  // 启用定时任务
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

定义定时任务

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
    // 固定频率:每5秒执行一次(从任务开始计时)
    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        System.out.println("固定频率执行:" + System.currentTimeMillis());
    }
    // 固定延迟:上次执行完成后延迟3秒再执行
    @Scheduled(fixedDelay = 3000)
    public void processData() {
        System.out.println("固定延迟执行:" + System.currentTimeMillis());
        // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    // 使用Cron表达式:每天上午9:30执行
    @Scheduled(cron = "0 30 9 * * ?")
    public void dailyReport() {
        System.out.println("每日报告生成:" + System.currentTimeMillis());
    }
    // 带初始延迟:延迟10秒后,再每2秒执行一次
    @Scheduled(fixedRate = 2000, initialDelay = 10000)
    public void delayedTask() {
        System.out.println("延迟后执行:" + System.currentTimeMillis());
    }
}

注意事项

  • 默认所有任务共用一个线程池(线程数为1),可通过配置修改
  • 方法不能有参数,返回类型为void

配置线程池(可选)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 设置线程池大小,避免一个任务阻塞其他任务
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
    }
}

分布式场景:Redis + Redisson的分布式调度

适合多实例部署的微服务,避免任务重复执行。

import org.redisson.api.RScheduledExecutorService;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DistributedScheduler {
    @Autowired
    private RedissonClient redissonClient;
    public void scheduleDistributedTask() {
        RScheduledExecutorService executor = redissonClient.getExecutorService("myTasks");
        // 提交一个延迟任务,只会被一个实例执行
        executor.schedule(() -> {
            System.out.println("分布式定时任务执行,当前实例:" + System.currentTimeMillis());
            // 业务逻辑
        }, 10, java.util.concurrent.TimeUnit.SECONDS);
    }
}

选择建议

场景 推荐方案
简单单次/固定周期任务 TimerScheduledExecutorService
Spring Boot项目,简单任务 @Scheduled 注解
复杂调度(Cron表达式) Spring Boot + Quartz
大规模、高可用分布式系统 Quartz集群 或 分布式调度框架(xxl-job, Elastic-Job)
微服务多实例防重复执行 Redis分布式锁 + @Scheduled

我个人最推荐 Spring Boot的 @Scheduled 注解,简单高效,日常80%的需求都能满足,如果需要Cron表达式支持复杂调度,配合Quartz是业界标准方案。

抱歉,评论功能暂时关闭!