几种方式实现定时任务

Thread 实现定时任务

public static void threadTask() {
    new Thread(() -> {
        while (true) {
            try {
                System.out.println("doSomething");
                Thread.sleep(1000 * 5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }).start();
}
  • 学习成本低,只适用于简单的周期性任务

Timer 类实现定时任务

  • JDK 提供的定时器工具类
public static void timerTask() {
    Timer timer = new Timer();
    
    // 延迟 2s ,每隔 1s 循环执行
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            log.info("doSomething1");
        }
    }, 2000, 1000);
    
    // 在指定时间执行
    Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2023-03-02 10:24:00");
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            log.info("doSomething1");
        }
    }, date);
}
  • Timer 类对象被创建出来后就会启动一个线程,调用该对象的 schedule 方法就是利用该线程进行一些定时任务的操作
  • Timer 类对象是单线程执行任务,其中一个任务执行时间比较长会影响到其他任务
  • 某个 TimerTask 抛出异常,Timer 会停止线程,导致所有任务停止运行
  • schedule 有以下六种使用方式
// 指定任务 task 在指定时间 time 执行
schedule(TimerTask task, Date time);

// 指定任务 task 在指定延迟 delay 后执行
schedule(TimerTask task, long delay);

// 指定任务 task 在指定时间 firstTime 执行后,进行重复固定延迟频率 peroid 的执行(执行结束后开始算间隔时间)
schedule(TimerTask task, Date firstTime,long period);

// 指定任务 task 在指定延迟 delay 后,进行重复固定延迟频率 peroid 的执行(执行结束后开始算间隔时间)
schedule(TimerTask task, long delay, long period);

// 类似于入参相同的 schedule 方法,不同的是该方法更关注时间(执行开始时开始算间隔时间),而 schedule 更关注间隔
scheduleAtFixedRate(TimerTask task,Date firstTime,long period);

// 类似于入参相同的 schedule 方法,不同的是该方法更关注时间(执行开始时开始算间隔时间),而 schedule 更关注间隔
scheduleAtFixedRate(TimerTask task, long delay, long period);

ScheduledExecutorService 类实现定时任务

  • JDK 1.5 引入的新的定时任务类;基于线程池,设计的初衷就是解决 Timer 类的单线程执行问题;并且每个线程间不会相互影响
public static void ScheduledExecutorServiceTask() {
    // 创建 ScheduledExecutorService 对象,指定线程数为 5
    ScheduledExecutorService ses = Executors.newScheduledThreadPool(5);
    ses.scheduleAtFixedRate(() -> {
        System.out.println("doSomething");
    }, 1000, 1000, TimeUnit.MILLISECONDS);
}
  • ScheduledExecutorService 有以下四种使用方式(整体和 Timer 差别不大)
// 指定任务 command 在指定延迟 delay 后执行
schedule(Runnable command, long delay, TimeUnit unit);

// Callable 待学习
schedule(Callable<V> callable, long delay, TimeUnit unit);

// 指定任务 command 在指定延迟 initialDelay 后,进行重复固定延迟频率 peroid 的执行(执行开始时开始算间隔时间)
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

// 指定任务 command 在指定延迟 initialDelay 后,进行重复固定延迟频率 delay 的执行(执行结束后开始算间隔时间)
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);

Spring 封装的定时任务使用

// 在启动类上添加如下注解
@EnableScheduling

// 创建定时任务
@Component
@Slf4j
public class SpringTask {

    // 定时任务规则(配置到配置文件中即可,自动读取,这里配置的是 "* * * * * ?" 每秒执行;有在线的 corn 生成器)
    @Scheduled(cron = "${sue.spring.task.cron}")
    public void task() {
        log.info("doSomething");
    }
}
  • Springboot 内部使用的就是 ScheduledExecutorService ,corn 以执行开始时间判断间隔,还有其他方式使用时在进行了解
  • Spring 默认创建线程数为 1 的线程池,可以通过配置文件进行调整
spring:
	task:
  	scheduling:
    	thread-name-prefix: scheduling-
    	pool:
      	size: 5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值