spring定时任务

        定时任务,即特定条件下触发,常用于业务周期性维护,如数据同步,业务检查,定期的业务处理...

        定时任务要素:时机,执行。时机,即定时任务触发时机,执行,着重考虑的线程执行,串行或并行,线程维护。

环境配置:springboot

时机

@Scheduled 注解控制时机。控制参数

fixedRate:两次任务执行间隔,自带修正。

fixedRate:距离上次任务间隔

initialDelay:第一次执行间隔

cron:cron表达式

      cron表达式(注意区分linux的cron表达式,linux精确到min,spring cron 精确到s),共七个占位符,第七个为可选项。

second, minute, hour, day, month, weekday,year


       其中星期与月可用英文名称的前三个字母

         通用符号,“,-*/”

  • 逗号,列表值,
  • 减号-,范围,如“10-13”等同于“10,11,1213"
  • *,每一个时刻
  • /,等步长序列,x/y,x是起点,y是步长

        特殊字符

  • ? 无意义的值。用于星期中。(星期与日不能同时实现,使用?进行兼容)
  • nL  每月最后第n天或每个星期最后第n天(星期六)
  • nW  离每月第n天最近的工作日(周一至周五,不能跨月),LW连用,本月最后一个工作日
  • x#y 本月第y周的星期x-1(星期中7表示星期六)
  • nC 本月(或星期)后n天

执行

       每个定时任务都会开启一个线程进行,指定线程执行器ScheduledThreadPoolExecutor执行。为了更细粒度的控制线程,可以使用方法级别的异步,指定执行器ThreadPoolTaskExecutor。

相关代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>zl</groupId>
	<artifactId>example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>schedule</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.10.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

application

package zl.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages="zl.example.config")
public class ScheduleApplication {

	public static void main(String[] args) {
		SpringApplication.run(ScheduleApplication.class, args);
	}
}

定时任务执行器

package zl.example.config;

import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
@EnableScheduling
@ComponentScan(basePackages="zl.example.task")
public class ScheduleConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
    	ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);  
         executor.setMaximumPoolSize(100);
         executor.setKeepAliveTime(300, TimeUnit.SECONDS);
         executor.setRejectedExecutionHandler(new ScheduledThreadPoolExecutor.CallerRunsPolicy());  
         return executor;  
         
         //可以满足,至少是个10个任务在运行,30个任务在等待(多余的任务会创建新的线程),空闲线程300s不活动被销毁
   
         // rejection-policy:当pool已经达到max size的时候,如何处理新任务  
         // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行  
      /*   Reject策略预定义有四种: 
         (1)ThreadPoolExecutor.AbortPolicy策略,是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。 
         (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃. 
         (3)ThreadPoolExecutor.DiscardPolicy策略,不能执行的任务将被丢弃. 
         (4)ThreadPoolExecutor.DiscardOldestPolicy策略,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程).*/
    }

}

   方法异步执行器

package zl.example.config;

import java.util.concurrent.Executor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@EnableAsync
@ComponentScan(basePackages="zl.example.task")
public class AsyncConfig implements AsyncConfigurer  {   
	@Override
    public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(7);
    executor.setMaxPoolSize(42);
    executor.setQueueCapacity(11);
    executor.setThreadNamePrefix("MyAsyncExecutor-");
    executor.initialize();
    return executor;
}

	@Override
	public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		return null;
	}

}

   异步方法

package zl.example.task;

import java.util.Calendar;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

@Component
public class AsyncExample {
	
	@Async
	public Future<String> async(){
		try {
			TimeUnit.SECONDS.sleep(20);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("excute async " + Calendar.getInstance().get(Calendar.SECOND));
		return new AsyncResult<>("async accomplished!");  
	}
}

定时任务

package zl.example.task;

import java.util.Calendar;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduleExample {
	@Autowired
	AsyncExample example;
	
	@Scheduled(fixedRate=1000)
	public void fixedRate(){//自带修正功能
		System.out.println("excute fixedRate " + Calendar.getInstance().get(Calendar.SECOND));
	}
	
	@Scheduled(fixedRate=2000)
	public void initialDelay(){
		Future<String> async = example.async();
		System.out.println("async finished ? "+  async.isDone());
		System.out.println("excute fixedRate " + Calendar.getInstance().get(Calendar.SECOND));
	}
	
	@Scheduled(fixedDelay=1000)
	public void fixedDelay() {
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("excute fixedDelay " + Calendar.getInstance().get(Calendar.SECOND));
	}
	
	@Scheduled(cron="0 0 0 * 2 ?")
	public void cron() {
		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值