创建定时任务

import com.babyeye.dao.UserDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;import java.text.SimpleDateFormat;/*** @author Holley* @Description 定时任务* @create 2018-08-30 14:29**/
@Service
public class ScheduledTaskService {private Logger log = LoggerFactory.getLogger(ScheduledTaskService.class);private SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD hh:mm:ss");@Autowiredprivate UserDAO userDAO;/*** @Author holley* @Description 每天早上八点将到期账号设置为已过期状态* @Date 2018/8/30 15:04* @Param []* @return void*/@Scheduled(cron = "0 0 8 * * ?")public void accountOverdue(){userDAO.overdueAccount();}/*** @Author holley* @Description 延迟5秒执行一次* @Date 2018/8/30 15:35* @Param []* @return void*/@Scheduled(fixedDelay = 5000)public void testFixedDelay(){log.info("执行fixedDelay测试方法:" + sdf.format(System.currentTimeMillis()));}/*** @Author holley* @Description 5秒执行一次* @Date 2018/8/30 15:36* @Param []* @return void*/@Scheduled(fixedRate = 5000)public void testFixedRate(){log.info("执行fixedRate测试方法:" + sdf.format(System.currentTimeMillis()));}/*** @Author holley* @Description 第一次延迟三秒执行,之后每5秒执行一次* @Date 2018/8/30 15:39* @Param []* @return void*/@Scheduled(initialDelay = 3000,fixedRate = 5000)public void testInitialDelay(){log.info("执行initialDelay测试方法:" + sdf.format(System.currentTimeMillis()));}}

开启定时任务

import com.babyeye.interceptor.Interceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@ServletComponentScan
@SpringBootApplication
@EnableScheduling
public class OkjingApplication {public static void main(String[] args) {SpringApplication.run(OkjingApplication.class, args);}}

下面开始介绍下secheduled的参数都有哪些:

1.fixedDelay: 表示上一次任务执行多久后再次执行,参数类型是Long,单位毫秒

2.fixedDelayString : 与fixedDelay含义一样,只是参数类型变成了String

3.fixedRate : 表示按照一定的频率执行任务,参数类型是Long,单位毫秒

4.fixedRateString : 和fixedRate含义一样,只是参数类型变成了String

5.initialDelay : 表示延迟多久开始执行第一次任务,参数类型Long,单位毫秒

6.initialDelayString : 与initialDelay含义一样,只是参数类型变成了String

7.cron : cron表达式,指定任务在特定时间执行

  cron表达式定义:

    Cron表达式是一个字符串,由空格隔开的6个或7个域组成,每个域对应一个含义(秒,分,时,日,月,周 ,年),其中年是可选字段,但是spring的scheduled只支持前6个域的表达式,也就是不能设置年,如果超过则会报错

    每个域中可出现的字符类型及含义:

(1)各域支持的字符类型

秒:可出现", - * /"四个字符,有效范围为0-59的整数

分:可出现", - * /"四个字符,有效范围为0-59的整数

时:可出现", - * /"四个字符,有效范围为0-23的整数

每月第几天:可出现", - * / ? L W C"八个字符,有效范围为0-31的整数

月:可出现", - * /"四个字符,有效范围为1-12的整数或JAN-DEc

星期:可出现", - * / ? L C #"四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推

(2)特殊字符含义

 * : 表示匹配该域的任意值,比如在秒*, 就表示每秒都会触发事件。;

    ? : 只能用在每月第几天和星期两个域。表示不指定值,当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”;

    - : 表示范围,例如在分域使用5-20,表示从5分到20分钟每分钟触发一次  

    / : 表示起始时间开始触发,然后每隔固定时间触发一次,例如在分域使用5/20,则意味着每小时的第5分,25分,45分,分别触发一次.  

    , : 表示列出枚举值。例如:在分域使用5,20,则意味着在5和20分时触发一次。  

    L : 表示最后,只能出现在星期和每月第几天域,如果在星期域使用1L,意味着在最后的一个星期日触发。  

    W : 表示有效工作日(周一到周五),只能出现在每月第几日域,系统将在离指定日期的最近的有效工作日触发事件。注意一点,W的最近寻找不会跨过月份  

    LW : 这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。  

    # : 用于确定每个月第几个星期几,只能出现在每月第几天域。例如在1#3,表示某月的第三个星期日。

   C:代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。

实例:

"0 0 * * * *"                      表示每小时0分0秒执行一次

" */10 * * * * *"                 表示每10秒执行一次

"0 0 8-10 * * *"                 表示每天8,9,10点执行

"0 0/30 8-10 * * *"            表示每天8点整开始到10点,每半小时执行

"0 0 9-17 * * 2-6"     表示每周一至周五,9点到17点的0分0秒执行

"0 0 0 25 12 ?"                  表示每年圣诞节(12月25日)0时0分0秒执行

8.zone : 时区,默认为当前时区,一般没有用到

多线程执行

不知道有没有人注意到上面代码执行结果打印出来的log,在截图中我们可以发现被执行的每个任务都是被同一个线程所调用,这是因为在pspring中如果没有自定义设置线程池时,会默认创建一个单线程的线程池。这样的话,如果定时任务增多,就会容易造成阻塞。

如果改成多线程执行,在springboot中有两种方法。

一。实现SchedulingConfigurer接口,重写configureTasks方法即可,代码如下:

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 ScheduleConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {//设定一个长度10的定时任务线程池taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));}}

二。使用config配置类的方式添加配置,然后需要在定时任务的类或方法上添加@Async注解,代码如下:

@Configuration // 表明该类是一个配置类
@EnableAsync  // 开启异步支持
public class AsyncConfig {/*此处成员变量应该使用@Value从配置中读取*/private int corePoolSize = 10;private int maxPoolSize = 200;private int queueCapacity = 10;@Beanpublic Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(corePoolSize);executor.setMaxPoolSize(maxPoolSize);executor.setQueueCapacity(queueCapacity);executor.initialize();return executor;}
}

/*** @author Holley* @Description 定时任务* @create 2018-08-30 14:29**/
@Async
@Service
public class ScheduledTaskService {private Logger log = LoggerFactory.getLogger(ScheduledTaskService.class);@Autowiredprivate UserDAO userDAO;/*** @Author holley* @Description 每天早上八点将到期账号设置为已过期状态* @Date 2018/8/30 15:04* @Param []* @return void*/@Scheduled(cron = "0 0 8 * * ?")public void accountOverdue(){userDAO.overdueAccount();}
}

除了上述的spring task 的scheduled之外,还有如下几种方式可以实现定时任务:

1.Timer:java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务,使用这种方式可以按照某一频率来执行,而不能设置指定时间,demo如下:

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;/*** @author Holley* @Description 请输入一句话进行描述* @create 2018-08-31 10:45**/
public class TimerDemo {public static void main(String[] args) {TimerTask timerTask = new TimerTask() {@Overridepublic void run() {System.out.println("task  run:"+ new Date());}};Timer timer = new Timer();System.out.println(new Date());//安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次timer.schedule(timerTask,10000,3000);}
}

执行结果如下:

2.ScheduledExcutorService:也是jdk自带的一个类,是基于线程设计的定时任务,每个调度任务都会分配到线程池中的一个线程去执行,因此任务是并发执行的。demo如下:

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** @author Holley* @Description 请输入一句话进行描述* @create 2018-08-31 10:58**/
public class ScheduleExecutorService {public static void main(String[] args) {ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();// java8的Lambda表达式 参数:1、任务体 2、首次执行的延时时间//      3、任务执行间隔 4、间隔时间单位service.scheduleAtFixedRate(() -> System.out.println("task ScheduledExecutorService " + new Date()), 0, 3, TimeUnit.SECONDS);}
}

在此demo中使用了java8的Lambda表达式,如果对此表达式不了解的可以参考下:https://www.cnblogs.com/andywithu/p/7357069.html

3.Quartz:这是一个功能比较强大的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来比较复杂,还需要添加依赖

  如果SpringBoot版本是2.0.0以后的,则在spring-boot-starter中已经包含了quart的依赖,则可以直接使用spring-boot-starter-quartz依赖:

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

  如果SpringBoot版本是1.5.9则要使用以下依赖

<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId>
</dependency>

  • 创建任务类TestQuartz,该类主要是继承了QuartzJobBean
public class TestQuartz extends QuartzJobBean {/*** 执行定时任务* @param jobExecutionContext* @throws JobExecutionException*/@Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.out.println("quartz task "+new Date());}
}

  • 创建配置类QuartzConfig

    @Configuration
    public class QuartzConfig {@Beanpublic JobDetail teatQuartzDetail(){return JobBuilder.newJob(TestQuartz.class).withIdentity("testQuartz").storeDurably().build();}@Beanpublic Trigger testQuartzTrigger(){SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10)  //设置时间周期单位秒
                    .repeatForever();return TriggerBuilder.newTrigger().forJob(teatQuartzDetail()).withIdentity("testQuartz").withSchedule(scheduleBuilder).build();}
    }

    关于Quartz的详细内容可以查看官方文档:http://www.quartz-scheduler.org/documentation/

参考:https://blog.csdn.net/ninifengs/article/details/77141240

      https://blog.csdn.net/wqh8522/article/details/79224290

转载于:https://www.cnblogs.com/zhlblogs/p/9561733.html

spring的定时任务schedule相关推荐

  1. spring cloud 定时任务

    项目中,因为使用了第三方支付(支付宝和微信支付),支付完毕后,第三方支付平台一般会采用异步回调通知的方式,通知商户支付结果,然后商户根据通知内容,变更商户项目支付订单的状态.一般来说,为了防止商户项目 ...

  2. 【Spring】定时任务

    spring的定时任务: 1)简单的有Java自带的Timer. ScheduledExecutorService, Spring自带的Task. 2)相较复杂的分布式定时任务中间件有XXL-JOB. ...

  3. spring boot-shedule 定时任务的使用

    spring boot已经集成了定时任务,以下是springboot集成shedule的方法和一些常用的场景的配置方式的示例. 1. 工程目录 2.application.yml配置 spring:a ...

  4. Java Spring @Scheduled 定时任务crontab表达式设置

    Java Spring @Scheduled 定时任务crontab表达式设置 1. Cron详解 2. 例子 参考 1. Cron详解 Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或 ...

  5. Spring之定时任务基本使用篇

    文章链接:https://liuyueyi.github.io/hexblog/2018/08/01/180801-Spring之定时任务基本使用篇/ Spring之定时任务基本使用篇 spring- ...

  6. Spring Boot定时任务应用实践

    在Spring Boot中实现定时任务功能,可以通过Spring自带的定时任务调度,也可以通过集成经典开源组件Quartz实现任务调度. 一.Spring定时器 1.cron表达式方式 使用自带的定时 ...

  7. Spring Task定时任务的配置和使用详解

    spring中使用定时任务 1.基于xml配置文件使用定时任务 首先配置spring开启定时任务 <beans xmlns="http://www.springframework.or ...

  8. spring 配置定时任务

    spring的定时任务配置分为三个步骤: 1.定义任务 2.任务执行策略配置 3.启动任务 1.定义任务 <!--要定时执行的方法--> <bean id="testTas ...

  9. @scheduled注解配置时间_Java开发重写Spring Boot定时任务,支持可动态调整执行时间...

    Spring Boot应该是目前最火的java开源框架了,它简化了我们创建一个web服务的过程,让我们可以在很短时间.基本零配置就可以启动一个web服务. 定时任务在我们平常的业务开发用的非常多,Sp ...

最新文章

  1. 自动驾驶:蛇形曲线跟踪(Stanley Model)
  2. Jmeter之Json表达式关联
  3. 【Flink】Flink Table SQL 用户自定义函数: UDF、UDAF、UDTF
  4. python输入错误提示再次输入_Python实现用户登录并且输入错误三次后锁定该用户...
  5. 网络丢包诊断与分析的现实与理想
  6. HiveSQL技术原理、优化[深度解析]
  7. Makeflie自动生成依赖,自动化编译
  8. linux Audit 介绍【架构篇】
  9. Linux 环境下思源黑体字体与 Java 之间的兼容性问题的解决(补充说明)
  10. 社招腾讯,阿里,京东,必问知识点整理,常考知识点全在这里了!
  11. 电脑键盘部分按键失灵_笔记本键盘一部分失灵怎么办(笔记本个别键失灵的解决方法)...
  12. 华为路由器isis配置实例_华为-ISIS路由协议(原理+配置实操)
  13. Linux中的vim最小集、指令集及其配置
  14. UltraEdit 19.10版本花括号自动缩进两空格的解决方法
  15. Git 到底是个什么东西?
  16. 冒泡排序从左到右 从右到左方法实现(三种方法)
  17. Eugene Fama —— 一段 50 年的传奇
  18. 先验算法(Apriori Algorithm)原理及python代码实现
  19. Swift 现可使用 Checkmarx 检查代码出错
  20. verilog实现简单的除法运算

热门文章

  1. 复用:设计模式 反模式 分析模式
  2. 安全编码最佳实践:PHP及编程语言安全
  3. [Algorithm]一切始于ADT-表达式计算
  4. 输入一个数,求1到他 的和(for循环)
  5. Virtualbox虚拟机Linux Guest的Additions安装方法
  6. JSP:src路径里有中文,产生乱码问题
  7. 上一篇的改进!!!!!
  8. 刚在网上搜资料,搜出一段话,觉得很有感触~
  9. encoder decoder模型_3分钟|聊一聊 Decoder 模块
  10. 充分发挥计算机在教学中的辅助作,充分发挥计算机在教学中的辅助作用