序言

对于定时任务,在SpringBoot中只需要使用@Scheduled 这个注解就能够满足需求,它的出现也给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用定时任务了。

但是,我们需要注意的是,@Scheduled 并不一定会按时执行

因为使用@Scheduled 的定时任务虽然是异步执行的,但是,不同的定时任务之间并不是并行的!!!!!!!!

在其中一个定时任务没有执行完之前,其他的定时任务即使是到了执行时间,也是不会执行的,它们会进行排队。

也就是如果你想你不同的定时任务互不影响,到时间就会执行,那么你最好将你的定时任务方法自己搞成异步方法,这样,定时任务其实就相当于调用了一个线程执行任务,一瞬间就结束了。比如使用:@Async

当然,也可以勉强将你的定时任务当做都会定时执行。但是,作为一个合格的程序员

那么,如何将@Scheduled实现的定时任务变成异步的呢?此时你需要对@Scheduled进行线程池配置。

配置示例

package com.java.navtool.business.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.config.ScheduledTaskRegistrar; import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor; /**
* @author :mmzsblog.cn
* @date :Created in 2021/7/27 17:46
* @description:spring-boot 多线程 @Scheduled注解 并发定时任务的解决方案
* @modified By:
* @version:
*/ @Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer { @Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
} public static final String EXECUTOR_SERVICE = "scheduledExecutor"; @Bean(EXECUTOR_SERVICE)
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
// 设置最大线程数
executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 10);
// 设置队列容量
executor.setQueueCapacity(Runtime.getRuntime().availableProcessors() * 10);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(10);
// 设置默认线程名称
executor.setThreadNamePrefix("scheduled-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
} }

附带介绍一下线程池的几个参数。需要彻底搞懂,不要死记硬背哦!

线程池参数

  • 1、corePoolSize(必填):核心线程数。
  • 2、maximumPoolSize(必填):最大线程数。
  • 3、keepAliveTime(必填):线程空闲时长。如果超过该时长,非核心线程就会被回收。
  • 4、unit(必填):指定keepAliveTime的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
  • 5、workQueue(必填):任务队列。通过线程池的execute()方法提交的Runnable对象将存储在该队列中。
  • 6、threadFactory(可选):线程工厂。一般就用默认的。
  • 7、handler(可选):拒绝策略。当线程数达到最大线程数时就要执行饱和策略。

说下核心线程数和最大线程数的区别:

拒绝策略可选值:

  • 1、AbortPolicy(默认):放弃任务并抛出RejectedExecutionException异常。
  • 2、CallerRunsPolicy:由调用线程处理该任务。
  • 3、DiscardPolicy:放弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。
  • 4、DiscardOldestPolicy:放弃队列最早的未处理任务,然后重新尝试执行任务。

线程池执行流程:

上个流程图,先试着自己看下能不能看懂:

简短的总结下线程池执行流程:

  • 1、一个任务提交到线程池后,如果当前的线程数没达到核心线程数,则新建一个线程并且执行新任务,注意一点,这个新任务执行完后,该线程不会被销毁;
  • 2、如果达到了,则判断任务队列满了没,如果没满,则将任务放入任务队列;
  • 3、如果满了,则判断当前线程数量是否达到最大线程数,如果没达到,则创建新线程来执行任务,注意,如果线程池中线程数量大于核心线程数,每当有线程超过了空闲时间,就会被销毁,直到线程数量不大于核心线程数;
  • 4、如果达到了最大线程数,并且任务队列满了,就会执行饱和策略;

玩转SpringBoot之定时任务@Scheduled线程池配置的更多相关文章

  1. SpringBoot普通消息队列线程池配置

    1 package com.liuhuan.study.config; 2 3 import com.google.common.util.concurrent.ThreadFactoryBuilde ...

  2. SpringBoot 线程池配置 实现AsyncConfigurer接口方法

      目的是:  通过实现AsyncConfigurer自定义线程池,包含异常处理  实现AsyncConfigurer接口对异常线程池更加细粒度的控制 *a) 创建线程自己的线程池  b) 对void ...

  3. Spring线程池配置模板设计(基于Springboot)

    目录 线程池配置模板 基础的注解解释 常用配置参数 配置类设计 线程池使用 ThreadPoolTaskExecutor源码 线程池配置模板 springboot给我们提供了一个线程池的实现,它的底层 ...

  4. SpringBoot异步及线程池配置

    异步方法注解@Async 在SpringBoot中进行异步处理,可以使用异步注解@Async和@EnableAsync. @Async注解表示异步,如:@Async("asyncServic ...

  5. SpringBoot执行定时任务@Scheduled

    SpringBoot执行定时任务@Scheduled 在做项目时,需要一个定时任务来接收数据存入数据库,后端再写一个接口来提供该该数据的最新的那一条. 数据保持最新:设计字段sign的值(0,1)来设 ...

  6. TestNg线程池配置、执行次数配置、超时配置

    使用注解的方式对TestNg线程池配置.执行次数配置.超时配置 注:使用注解来控制测试方法运行的次数和超时时间,timeOut在单线程或者多线程模式下都可用,threadPoolSize设置了线程池的 ...

  7. 【Java 并发】Executor框架机制与线程池配置使用

    [Java 并发]Executor框架机制与线程池配置使用 一,Executor框架Executor框架便是Java 5中引入的,其内部使用了线程池机制,在java.util.cocurrent 包下 ...

  8. TestNG的參数化測试、共享线程池配置、參数默认值配置

    在使用TestNG进行測试时,常常会使用到一些參数化配置,比方数据库.连接池.线程池数. 使用TestNG的參数@Parameter注解进行自己主动化读取 原创文章,版权全部.同意转载,标明出处:ht ...

  9. Hystrix线程池配置

    Hystrix配置文件配置 断路器: hystrix.command.default.circuitBreaker.requestVolumeThreshold(当在配置时间窗口内达到此数量的失败后, ...

随机推荐

  1. 【ybtoj】贪心算法例题

    [基础算法]第二章 贪心算法 例一 奶牛晒衣服 题目描述 有n件衣服,第i件衣服的湿度为h. 在自然条件下,每件衣服每分钟都可以自然晒干A点湿度. 在烘干机作用下,可以选择一件衣服,用一分钟的时间晒干 ...

  2. Linux CentOS 搭建SVN并用钩子自动实现同步到Web目录

    linux安装配置SVN并设置钩子   安装说明 系统环境:CentOS-6.3安装方式:yum install (源码安装容易产生版本兼容的问题)安装软件:系统自动下载SVN软件 检查已安装版本 # ...

  3. 拜托,使用Three.js让二维图片具有3D效果超酷的好吗 💥

    声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 逛 sketchfab 网站的时候我看到有很多二维平面转 3D 的模型例子 ...

  4. [题解]UVA10026 Shoemaker's Problem

    链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&am ...

  5. 8款国内外主流商业智能BI工具分析,助你轻松选型!

    BI(Business Intelligence),即商业智能或商务智能,它是一套完整的解决方案,用来将企业中现有的数据进行有效的整合,快速准确的提供报表并提出决策依据,帮助企业做出明智的业务经营决策 ...

  6. 3、如何查看window 下的cpu参数

    一.windows下查看CPU信息 windows系统使用systeminfo命令可以查看CPU信息,如: Intel64 Family 6 Model 158 Stepping 10 Genuine ...

  7. 修改Ehcache缓存中取到的值,缓存中的值也被修改了

    问题现象 我们从Ehcache中取出缓存的对象,之后将对象中的属性进行了修改使用.等再次从缓存中拿到对象后,发现对象的值变成了上一次调用修改后的对象了. 原因 Ehcache中缓存的是原对象的引用,所 ...

  8. golang程序设计:Go middleware中间件以及Gin 中间件分析

    先从业务开发角度出发,来逐渐引出中间件. 一.刚开始时业务开发 开始业务开发时,业务需求比较少. 当我们最开始进行业务开发时,需求不是很多. 第一个需求产是品向大家打声招呼:"hello w ...

  9. Qt:QDir

    0.说明 QDir提供了访问目录及目录下内容的类. QDir既可以用于访问文件系统,也可以用于访问Qt 资源系统(Qt's resource system.). Qt用 "/" 作 ...

  10. Qt:QList、QStringList

    QList 0.说明 QList<T> 一个QList是存储相同类型一组数据的列表. QStringList是从QList<String>继承而来,并添加了一些好用的方法,如j ...