定时器配置

本文详细介绍了在Spring框架下如何配置和使用定时任务,包括SpringTask和Quartz的配置方法,以及Cron表达式的解析和应用实例。

以下案例基于spring整合的方式使用,需导入spring相关坐标

一.Spring Task

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:task="http://www.springframework.org/schema/task"
       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.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd">
    <!--包扫描-->
    <context:component-scan base-package="com.task"/>

    <!--开启定时器注解驱动-->
    <task:annotation-driven scheduler="seckillGoodsScheduler" executor="seckillGoodsExecutor" />
    <!-- 调度线程池配置,配置任务总数来分配调度线程池的大小 -->
    <task:scheduler id="seckillGoodsScheduler" pool-size="10"/>
    <!-- 执行线程池配置,单独某个任务如果要异步的执行时,配置当前任务内的多线程池-->
    <task:executor id="seckillGoodsExecutor" pool-size="5"/>
</beans>

定时任务:

@Component
public class DemoTask {

    //每秒执行
    @Scheduled(cron = "* * * * * ?")
    public void startTask(){
        System.out.println("定时执行了startTask:" + new Date());
    }
}

二.Quartz

maven坐标:

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
  <version>2.2.1</version>
</dependency>
<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz-jobs</artifactId>
  <version>2.2.1</version>
</dependency>

自定义job:

package com.jobs;
/**
 * 自定义Job
 */
public class JobDemo {
    public void run(){
        System.out.println("定时方法执行了...");
    }
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/mvc
						http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://code.alibabatech.com/schema/dubbo
						http://code.alibabatech.com/schema/dubbo/dubbo.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 注册自定义Job -->
    <bean id="jobDemo" class="com.jobs.JobDemo"></bean>
	<!-- 注册JobDetail,作用是负责通过反射调用指定的Job -->
    <bean id="jobDetail" 
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!-- 注入目标对象 -->
        <property name="targetObject" ref="jobDemo"/>
        <!-- 注入目标方法 -->
        <property name="targetMethod" value="run"/>
    </bean>
    <!-- 注册一个触发器,指定任务触发的时间 -->
    <bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!-- 注入JobDetail -->
        <property name="jobDetail" ref="jobDetail"/>
        <!-- 指定触发的时间,基于Cron表达式 -->
        <property name="cronExpression">
            <value>0/10 * * * * ?</value>
        </property>
    </bean>
    <!-- 注册一个统一的调度工厂,通过这个调度工厂调度任务 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!-- 注入多个触发器 -->
        <property name="triggers">
            <list>
                <ref bean="myTrigger"/>
            </list>
        </property>
    </bean>
</beans>

三.Cron表达式

1.格式

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
(1)Seconds Minutes Hours DayofMonth Month DayofWeek Year
(2)Seconds Minutes Hours DayofMonth Month DayofWeek
cron从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份

各字段的含义:

字段允许值允许的特殊字符
秒(Seconds)0~59的整数, - * / 四个字符
分(Minutes)0~59的整数, - * / 四个字符
小时(Hours)0~23的整数, - * / 四个字符
日期(DayofMonth)1~31的整数(但是你需要考虑你月的天数),- * ? / L W C 八个字符
月份(Month)1~12的整数或者 JAN-DEC, - * / 四个字符
星期(DayofWeek)1~7的整数或者 SUN-SAT (1=SUN), - * ? / L C # 八个字符
年(可选,留空)(Year)1970~2099, - * / 四个字符

注意事项:
每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:

  1. :表示匹配该域的任意值。假如在Minutes域使用, 即表示每分钟都会触发事件。
  2. ?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法:
    13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。
  3. -:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
  4. /:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.
  5. ,:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
  6. L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
  7. W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在
    DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。
  8. LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
  9. #:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

2.示例

"0 0 10,14,16 * * ? " 每天上午10点,下午2点,4"0 0/30 9-17 * * ? " 朝九晚五工作时间内每半小时 
"0 0 12 ? * WED" 表示每个星期三中午12"0 0 12 * * ?" 每天中午12点触发 
"0 15 10 ? * *" 每天上午10:15触发 
"0 15 10 * * ?" 每天上午10:15触发 
"0 15 10 * * ? *" 每天上午10:15触发 
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发 
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:102:44触发 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
"0 15 10 15 * ?" 每月15日上午10:15触发 
"0 15 10 L * ?" 每月最后一日的上午10:15触发 
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

### 配置AT32F425微控制器的定时器 AT32F425微控制器内置多个定时器模块,包括通用定时器和高级定时器,适用于各种定时和PWM生成应用。以下是一个详细的配置指南: #### 1. 定时器的基本配置步骤 在使用定时器之前,需要先配置时钟源。AT32F425的定时器通常依赖于系统时钟(SYSCLK)或外部时钟源。以下是一个基本的定时器配置流程: - **初始化定时器的时钟源**:确保定时器的时钟源已经正确配置。AT32F425的时钟配置可以参考官方例程中的系统时钟设置[^2]。 - **配置定时器的寄存器**:根据需要设置定时器的计数模式(向上计数、向下计数或中央对齐模式)、预分频器(Prescaler)和自动重载寄存器(ARR)。 - **启用定时器中断(可选)**:如果需要在定时器溢出时触发中断,需配置相应的中断向量并启用全局中断。 #### 2. 示例代码:定时器初始化 以下是一个使用AT32F425的通用定时器(TIMx)进行定时的示例代码: ```c #include "at32f4xx.h" void TIM2_Init(void) { // 使能TIM2时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 定义TIM2的配置结构体 TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; // 设置定时器的预分频器和自动重载值 TIM_TimeBaseStruct.TIM_Prescaler = 83; // 预分频器值,假设系统时钟为84MHz,分频后为1MHz TIM_TimeBaseStruct.TIM_Period = 999; // 自动重载值,定时1ms TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 初始化TIM2 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct); // 启动TIM2 TIM_Cmd(TIM2, ENABLE); } ``` #### 3. 定时器中断配置 如果需要在定时器溢出时触发中断,可以通过以下步骤配置中断: - **配置NVIC**:设置定时器中断的优先级并启用中断通道。 - **编写中断服务程序**:在中断服务程序中处理定时器溢出事件。 ```c void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { // 清除中断标志 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 在此处添加用户代码 } } void TIM2_EnableInterrupt(void) { // 使能TIM2中断 TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 配置NVIC NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); } ``` #### 4. 注意事项 - **时钟配置**:确保系统时钟已经正确配置,否则定时器的精度将受到影响。AT32F425的时钟配置可以参考官方提供的例程[^2]。 - **调试接口**:如果启用了高级访问保护(FAP high level),调试接口(SWD)将被禁用,无法通过调试器进行烧录或调试[^5]。因此,在启用高级访问保护之前,请确保已经通过类似IAP的方式准备好更新代码的机制。 - **外部时钟源**:如果使用外部时钟源(如反相器制作的8MHz振荡器),请确保其稳定性[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值