Spring Task详细使用

一、定时任务的理解

定时任务即系统在特定时间执行一段代码,它的场景应用非常广泛:

  • 购买游戏的月卡会员后,系统每天给会员发放游戏资源。
  • 管理系统定时生成报表。
  • 定时清理系统垃圾。

定时任务的实现主要有以下几种方式:

1、Java自带的java.util.Timer类,这个类允许调度一个java.util.TimerTask任务。使用这种方式可以让程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
2、Quartz。这是一个功能比较强大的的调度器,可以让程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂。
3、Spring3.0以后自带Spring Task,可以将它看成一个轻量级的Quartz,使用起来比 Quartz简单许多,在课程中我们使用Spring Task实现定时任务

二、入门案例

创建SpringBoot项目,在启动类开启定时任务。

也就是在启动类上方添加@EnableScheduling注解即可开启定时任务,代码如下:

编写定时任务类 

启动项目,定时任务方法按照配置定时执行。 

OK,果然如此,每隔2秒输出当前时间

@Scheduled写在方法上方,指定该方法定时执行。常用参数如下:

  1. cron:cron表达式,定义方法执行的时间规则。
  2. fixedDelay:任务立即执行,之后每隔多久执行一次,单位是毫秒,上一次任务结束后计算下次执行的时间。

OK,先来一个案例,代码如下:任务结束后每隔五秒执行一次

效果如下: 

OK,果然如此,注意这个是任务结束后每隔五秒

initialDelay:项目启动后不马上执行定时器,根据initialDelay的值延时执行。 这里配合fixedDelay来结合测试演示一下:

OK,看运行结果也是隔了三秒才出现第一次打印时间,并且打印时间是隔六秒打印一次

三、多线程案例

Spring Task定时器默认是单线程的,如果项目中使用多个定时器,使用一个线程会造成效率低下。

比如说我们设置了两个定时任务,那么因为Spring Task是单线程,如果在第一个定时任务加了一个sleep方法,那么会等第一个方法响应后在执行第二个任务,就很浪费cpu运行时间。代码如下:

@Scheduled(cron = "* * * * * *")
    public void task3() throws InterruptedException {
        System.out.println(Thread.currentThread().getId()+"线程执行任务1 - "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        Thread.sleep(5000);
    }

    @Scheduled(cron = "* * * * * *")
    public void task4() throws InterruptedException {
        System.out.println(Thread.currentThread().getId()+"线程执行任务2 - "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

执行效果如下:可以看到是先执行了任务2,但是他们都要隔五秒才能运行一次,因为通过线程号可以知道这是同一个线程。

因此任务1较浪费时间,会阻塞任务2的运行。此时我们可以给SpringTask配置线程池。代码如下:

@Configuration
public class SchedulingConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 创建线程池,设置五个线程
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(4));
    }
}

这样就不会出现阻塞问题了,因为两个任务不是同一个线程,接下来我们再次运行看看:

执行效果如上,确实不会影响到任务2的运行,但是如果定时任务过多,超过了配置的线程池的线程数量还是会运行错乱。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值