# 实现定时任务

在普通的 Java 程序中,可以通过以下几种方式实现定时任务:

# 1. 使用 TimerTimerTask

这是 Java 提供的基础定时任务实现方式。

# 示例:

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

public class TimerExample {
    public static void main(String[] args) {
        Timer timer = new Timer();

        // 定义任务
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("任务执行时间:" + System.currentTimeMillis());
            }
        };

        // 设置任务延迟 2 秒后执行,每隔 5 秒执行一次
        timer.schedule(task, 2000, 5000);

        // 如果需要任务只执行一次,可以使用 schedule(TimerTask task, long delay)
        // timer.schedule(task, 2000);
    }
}

注意

  • schedule(TimerTask task, long delay, long period):延迟 delay 毫秒后首次执行任务,之后每隔 period 毫秒执行一次。
  • Timer 是单线程执行,如果任务执行时间过长,可能会影响后续任务。

# 2. 使用 ScheduledExecutorService

ScheduledExecutorService 是 Java 并发库提供的一种更加灵活和高效的方式。

# 示例:

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

public class ScheduledExecutorExample {
    public static void main(String[] args) {
        // 创建线程池
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        // 定义任务
        Runnable task = () -> System.out.println("任务执行时间:" + System.currentTimeMillis());

        // 延迟 2 秒后每隔 5 秒执行一次
        scheduler.scheduleAtFixedRate(task, 2, 5, TimeUnit.SECONDS);

        // 如果只需要延迟执行一次,可以使用 schedule(Runnable command, long delay, TimeUnit unit)
        // scheduler.schedule(task, 2, TimeUnit.SECONDS);
    }
}

优点

  • 支持多线程任务。
  • 可以捕获和处理异常。
  • 可以控制延迟、间隔和精确的时间单位。

# 3. 使用 java.util.concurrentThreadsleep

这是最基础的定时方式,但需要自己控制线程和循环。

# 示例:

public class ThreadSleepExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    System.out.println("任务执行时间:" + System.currentTimeMillis());
                    Thread.sleep(5000); // 每隔 5 秒执行一次
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
    }
}

注意

  • 使用 Thread.sleep 需要自己管理线程生命周期。
  • 如果任务抛出异常,线程可能会终止。

# 4. 使用 Spring 的 @Scheduled(适用于 Spring 项目)

如果你的项目使用了 Spring 框架,可以使用 @Scheduled 注解实现定时任务。

# 示例:

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

@Component
public class ScheduledTaskExample {

    // 每隔 5 秒执行一次
    @Scheduled(fixedRate = 5000)
    public void runTask() {
        System.out.println("任务执行时间:" + System.currentTimeMillis());
    }
}

注意

  • 需要在配置类或启动类上添加 @EnableScheduling 注解。
  • 更适用于基于 Spring 的项目。

# 5. 使用第三方库(如 Quartz)

如果需要更加复杂和可配置的调度任务,可以使用 Quartz。

# 示例:

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzExample {
    public static void main(String[] args) throws SchedulerException {
        // 创建调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        // 定义任务
        JobDetail job = JobBuilder.newJob(MyJob.class)
                                  .withIdentity("myJob", "group1")
                                  .build();

        // 定义触发器
        Trigger trigger = TriggerBuilder.newTrigger()
                                        .withIdentity("myTrigger", "group1")
                                        .startNow()
                                        .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                                                                           .withIntervalInSeconds(5)
                                                                           .repeatForever())
                                        .build();

        // 开始调度
        scheduler.scheduleJob(job, trigger);
        scheduler.start();
    }

    public static class MyJob implements Job {
        @Override
        public void execute(JobExecutionContext context) {
            System.out.println("任务执行时间:" + System.currentTimeMillis());
        }
    }
}

优点

  • 支持复杂的任务调度(如 Cron 表达式)。
  • 适用于需要灵活调度的大型项目。

# 总结

  • 简单任务:使用 TimerScheduledExecutorService
  • 复杂任务:使用 Quartz 或 Spring @Scheduled
  • 轻量任务Thread.sleep 是最简单的实现。