原文地址: https://blog.csdn.net/yx0628/article/details/80873774

一个简单的Spring定时任务的 demo,全部代码见下载地址:https://download.csdn.net/download/yx0628/10511753 
对于 applicationContext 的配置如下:调度器线程池 task:scheduler 和 task:executor 的意义在后边例子中会详细的测试和说明。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd"
xmlns:task="http://www.springframework.org/schema/task"> <context:annotation-config /> <task:annotation-driven scheduler="myScheduler" executor="myExecutor"/> <!-- 调度线程池配置 -->
<task:scheduler id="myScheduler" pool-size="5"/>
<!-- 执行线程池配置 -->
<task:executor id="myExecutor" pool-size="5"/> <context:component-scan base-package="com.zaimeibian" /> </beans>a
package com.zaimeibian.task; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; @Component
public class PrintTask { DateFormat df = new SimpleDateFormat("HH:mm:ss"); // 这个Async注解,代表当前任务是要异步执行的
@Async
@Scheduled(fixedRate = 5000)
public void printA(){
System.out.println("A执行 " + df.format(new Date()));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
System.out.println("A打印输出 " + df.format(new Date())+ Thread.currentThread());
} @Scheduled(fixedRate = 5000)
public void printB(){
System.out.println("B执行 " + df.format(new Date()));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
System.out.println("B打印输出 " + df.format(new Date())+ Thread.currentThread());
} @Scheduled(fixedRate = 5000)
public void printC(){
System.out.println("C执行 " + df.format(new Date()));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
System.out.println("C打印输出 " + df.format(new Date())+ Thread.currentThread());
} // 配置initialDelay的任务是在容器启动后延迟一定时间才开始调度
@Scheduled(fixedRate = 5000, initialDelay=1000)
public void printD(){
System.out.println("D执行 " + df.format(new Date()));
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
}
System.out.println("D打印输出 " + df.format(new Date())+ Thread.currentThread());
} // 配置initialDelay的任务是在容器启动后延迟一定时间才开始调度
@Scheduled(fixedRate = 5000, initialDelay=1000)
public void printE(){
System.out.println("E执行 " + df.format(new Date()));
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
}
System.out.println("E打印输出 " + df.format(new Date())+ Thread.currentThread());
} }

这里,fixDelay 和 fixRate 参数代表每个任务,前者在上一个任务调度完成后,延迟一定的时间执行。而后者可以在每间隔一定时间就执行新任务(但这里与 executor 的参数有关)。下面的试验会详细说明这两个参数。 
Spring 的任务调度线程池,即

<task:scheduler id="myScheduler" pool-size="5"/>

如果不配置,那么默认值是 1 ,即结果是所有声明的任务,都是串行执行的,比如代码中的 A/B/C/D/E 五个任务,在默认值是 1 的情况下,只能一个个串行来执行。不能出现并行的情况。 
可以将参数改为 1 ,运行,输出如下:

B执行 12:16:36
B打印输出 12:16:46Thread[myScheduler-1,5,main]
A执行 12:16:46
A打印输出 12:16:56Thread[myScheduler-1,5,main]
C执行 12:16:56
C打印输出 12:17:06Thread[myScheduler-1,5,main]
D执行 12:17:06
D打印输出 12:17:36Thread[myScheduler-1,5,main]
E执行 12:17:36
E打印输出 12:18:06Thread[myScheduler-1,5,main]
B执行 12:18:06
B打印输出 12:18:16Thread[myScheduler-1,5,main]
A执行 12:18:16
A打印输出 12:18:26Thread[myScheduler-1,5,main]
C执行 12:18:26
C打印输出 12:18:36Thread[myScheduler-1,5,main]
D执行 12:18:36
D打印输出 12:19:06Thread[myScheduler-1,5,main]
E执行 12:19:06
E打印输出 12:19:36Thread[myScheduler-1,5,main]
B执行 12:19:36
B打印输出 12:19:46Thread[myScheduler-1,5,main]
A执行 12:19:46
A打印输出 12:19:56Thread[myScheduler-1,5,main]

可以看到只有 myScheduler-1 这一个调度线程来调度这五个任务,任务之间只能串行,即等待上个任务完成后释放调度线程,然后调度线程才能调度执行下一个任务。

然后我们还改回调度线程池 5 个线程池大小,运行:

C执行 12:23:04
A执行 12:23:04
B执行 12:23:04
E执行 12:23:05
D执行 12:23:05
C打印输出 12:23:14Thread[myScheduler-2,5,main]
C执行 12:23:14
A打印输出 12:23:14Thread[myScheduler-3,5,main]
A执行 12:23:14
B打印输出 12:23:14Thread[myScheduler-1,5,main]
B执行 12:23:14
C打印输出 12:23:24Thread[myScheduler-2,5,main]
C执行 12:23:24
A打印输出 12:23:24Thread[myScheduler-3,5,main]
A执行 12:23:24
B打印输出 12:23:24Thread[myScheduler-1,5,main]
B执行 12:23:24
C打印输出 12:23:34Thread[myScheduler-2,5,main]
A打印输出 12:23:34Thread[myScheduler-3,5,main]
C执行 12:23:34
A执行 12:23:34
B打印输出 12:23:34Thread[myScheduler-1,5,main]
B执行 12:23:34
E打印输出 12:23:35Thread[myScheduler-4,5,main]
E执行 12:23:35
D打印输出 12:23:35Thread[myScheduler-5,5,main]
D执行 12:23:35

可以看到,如果每个任务都有一个调度线程来处理,那么就是很理想的情况,各个任务之间是并行的,互不干扰各自独立,按照各自的时间来触发。(可以看到 1-5 这 5 个线程都在各自调度自己的任务) 
这里还要注意一点,fixDelay 和 fixRate 看上去似乎是一样的,在每个任务的调度线程中,都是必须上一个执行完毕后,等待配置的时间后,再开始下一次的执行。是不是 fixRate 参数不起作用呢?因为不是说 fixRate 是间隔一定时间执行,而不需要等待上一个任务执行完毕么?

这里引入另一个参数,可以看任务 A 上方注释掉的 @Async 注解:这个注解,代表可以异步执行。异步执行的话,调度线程池就会不用当前调度线程来执行,而是交给 task:executor 这个执行线程池来执行。 
我们来运行,这里为了更好的说明,我们可以把 A 的 fixRate 改为 2秒 ,看运行结果:

B执行 12:34:44
C执行 12:34:44
A执行 12:34:44
D执行 12:34:45
E执行 12:34:45
A执行 12:34:46
A执行 12:34:48
A执行 12:34:50
A执行 12:34:52
B打印输出 12:34:54Thread[myScheduler-2,5,main]
B执行 12:34:54
C打印输出 12:34:54Thread[myScheduler-3,5,main]
A打印输出 12:34:54Thread[myExecutor-1,5,main]
C执行 12:34:54
A执行 12:34:54
A打印输出 12:34:56Thread[myExecutor-2,5,main]
A执行 12:34:56
A打印输出 12:34:58Thread[myExecutor-3,5,main]
A执行 12:34:58
A打印输出 12:35:00Thread[myExecutor-4,5,main]
A执行 12:35:00
A打印输出 12:35:02Thread[myExecutor-5,5,main]
A执行 12:35:02
B打印输出 12:35:04Thread[myScheduler-2,5,main]
B执行 12:35:04
C打印输出 12:35:04Thread[myScheduler-3,5,main]
A打印输出 12:35:04Thread[myExecutor-1,5,main]
C执行 12:35:04
A执行 12:35:04
A打印输出 12:35:06Thread[myExecutor-2,5,main]

这里 A 任务的线程是 myExecutor-1 到 myExecutor-5,说明 myScheduler-1 这个调度线程调度了 A 任务,但是交给了线程池中的 myExecutor 中的执行线程来具体执行的。 
所以,配置 task:scheduler 参数的线程池,是为了根据任务总数来分配调度线程池的大小;而配置 task:executor ,是为了某个任务如果要异步的执行时,实现当前任务内的多线程并发。

Spring的任务调度@Scheduled注解——task:scheduler和task:executor的解析的更多相关文章

  1. Spring Boot中@Scheduled注解的使用方法

    Spring Boot中@Scheduled注解的使用方法 一.定时任务注解为@Scheduled,使用方式举例如下 //定义一个按时间执行的定时任务,在每天16:00执行一次. @Scheduled ...

  2. 使用spring提供的@Scheduled注解创建定时任务

    使用方法 操作非常简单,只要按如下几个步骤配置即可 1. 导入jar包或添加依赖,其实定时任务只需要spring-context即可,当然起服务还需要spring-web: 2. 编写定时任务类和方法 ...

  3. spring定时任务(@Scheduled注解)

    (一)在xml里加入task的命名空间 xmlns:task="http://www.springframework.org/schema/task" http://www.spr ...

  4. Spring Boot 使用 @Scheduled 注解创建定时任务

    在项目开发中我们经常需要一些定时任务来处理一些特殊的任务,比如定时检查订单的状态.定时同步数据等等. 在 Spring Boot 中使用 @Scheduled 注解创建定时任务非常简单,只需要两步操作 ...

  5. Spring系列:Scheduled注解学习笔记

    一.试验代码 //@Scheduled(fixedRate = 5000) //@Scheduled(fixedDelay = 5000) @Scheduled(cron ="*/5 * * ...

  6. spring定时任务(@Scheduled注解)cron表达式详解

    cron表达式详解: 一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素. 按顺序依次为 秒(~) 分钟(~) 小时(~) 天(~) 月(~) 星期(~ =SUN 或 SUN,MON,TU ...

  7. 使用C#创建计划任务(How to create a Task Scheduler use C# )

    本文主要讲解了如何使用C#来创建windows计划任务. 需求:在不定时间段运行多个后台程序(winfrom,wpf,console,等等)用于更新数据.  问题:为什么要使用计划任务,而不直接在程序 ...

  8. 使用轻量级Spring @Scheduled注解执行定时任务

    WEB项目中需要加入一个定时执行任务,可以使用Quartz来实现,由于项目就一个定时任务,所以想简单点,不用去配置那些Quartz的配置文件,所以就采用了Spring @Scheduled注解来实现了 ...

  9. 基于@Scheduled注解的Spring定时任务

    1.创建spring-task.xml 在xml文件中加入命名空间 <beans xmlns="http://www.springframework.org/schema/beans& ...

随机推荐

  1. 03011_预处理对象executeUpdate方法(实现数据库的增、删、改)

    1.概述 (1)通过预处理对象的executeUpdate方法,完成记录的insert\update\delete语句的执行: (2)操作格式统一如下: ①注册驱动: ②获取连接: ③获取预处理对象: ...

  2. js中对数组的操作-------Day49

    今天碰到了一个问题:easyui的使用中,datagrid表格的高度怎样改变(设定成一个固定的高度),看了半天文档,也从网上查了些.还楞是没弄出来,有点小郁闷.这easyui在某些情况情况下确实好用了 ...

  3. CSS demo:flaot &amp; clear float

    1,首先,我们布局主要的div块: 例如以下代码所看到的,我们在body里面写3几个基本div块,然后设置一些基本属性: 效果图: 2,增加基本浮动 如今我们想让红色div放到绿色div右边,我们在两 ...

  4. JavaScript学习总结(4)——JavaScript数组

    JavaScript中的Array对象就是数组,首先是一个动态数组,无需预先制定大小,而且是一个像Java中数组.ArrayList.Hashtable等的超强综合体. 一.数组的声明 常规方式声明: ...

  5. COGS——T 1265. [NOIP2012] 同余方程

    http://cogs.pro/cogs/problem/problem.php?pid=1265 ★☆   输入文件:mod.in   输出文件:mod.out   简单对比时间限制:1 s   内 ...

  6. 洛谷 P1724 东风谷早苗

    P1724 东风谷早苗 题目描述 在幻想乡,东风谷早苗是以高达控闻名的高中生宅巫女.某一天,早苗终于入手了最新款的钢达姆模型.作为最新的钢达姆,当然有了与以往不同的功能了,那就是它能够自动行走,厉害吧 ...

  7. ToggleButton控件

    ToggleButton 两种状态 ·状态button     -继承自CompoundButton ·主要属性:-Android:textOn    -Android:textOff ·主要方法: ...

  8. amazeui学习笔记一(开始使用4)--Web App 相关

    amazeui学习笔记一(开始使用4)--Web App 相关 一.总结 1.桌面图标(Touch icon)解决方案:终极方案:link标签的rel和href属性: <link rel=&qu ...

  9. wap.css

    wap.css 一.总结 1.官方有教程:英语的 http://www.developershome.com/wap/wcss/ 2.wap.css :就是控制页面在手机端样式的 3.DOCTYPE ...

  10. 100.dll调用

    在dll中声明 _declspec(dllexport) ; _declspec(dllexport)void go() { MessageBoxA(, ); } 调用dll HINSTANCE hl ...