SpringBoot——@Scheduled的自定义周期性线程池解决任务延时执行问题
关注微信公众号:CodingTechWork,一起学习进步。
问题
在使用Spring
中的@Scheduled
注解设置定时任务时,遇到这样2个问题:
- 定时任务未按时执行,现象是延后了一段时间才执行定时任务。
- 多个定时任务有时间重叠时,无法并发调度执行。
分析
出现上面问题现象的根因是Spring的定时任务默认是单线程执行,所以会在某些场景下造成阻塞。当然我们可以通过@Async
注解来异步执行这些并发的@Scheduled
注解的定时任务,而@Async
线程池容量是100,当超过100个线程并发执行时,则剩下的定时任务会等待之前的线程释放,不会自行扩容。
既然@Async是个定值大小的线程池,还是有出现定时任务延时执行的问题,所以下面我们可以通过其他方式来自定义线程池大小。
解决方式
通过自定义配置线程池来解决问题。
package com.andya.selfcode.conf;import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;import java.util.concurrent.*;/*** @author Andya* @create 2021-03-31*/
@Slf4j
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {//自定义线程池大小,可配置。代码中默认10个@Value("${threadPool.schedule.coreSize: 10}")public int SCHEDULE_CORE_SIZE;//自定义线程池名称public static final String THREAD_NAME_WITH_SCHEDULE = "schedule-thread-%d";@Overridepublic void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {// scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(SCHEDULE_CORE_SIZE));scheduledTaskRegistrar.setScheduler(this.buildSchedulerThreadPool());System.out.println("Scheduler threadpool core_size: " + SCHEDULE_CORE_SIZE);}/*** Spring的@Scheduled的自定义周期性线程池* @return*/@Bean(value = "scheduleThreadPool")public ExecutorService buildSchedulerThreadPool() {ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(THREAD_NAME_WITH_SCHEDULE).build();/*** 1. CallerRunsPolicy : 这个策略重试添加当前的任务,他会自动重复调用 execute() 方法,直到成功。2. AbortPolicy : 对拒绝任务抛弃处理,并且抛出异常。3. DiscardPolicy : 对拒绝任务直接无声抛弃,没有异常信息。4. DiscardOldestPolicy : 对拒绝任务不抛弃,而是抛弃队列里面等待最久的一个线程,然后把拒绝任务加到队列。不写则为默认的AbortPolicy策略。*/ScheduledExecutorService threadPool = new ScheduledThreadPoolExecutor(SCHEDULE_CORE_SIZE,threadFactory);return threadPool;}
}
SpringBoot——@Scheduled的自定义周期性线程池解决任务延时执行问题相关推荐
- 复盘SpringBoot中定时任务和异步线程池
作者:溪~源 blog.csdn.net/xuan_lu/article/details/110568508 项目中最近使用了多个定时任务处理业务需求,于是在实现业务逻辑过程中,产生了上图一些思考和疑 ...
- SpringBoot中的异步操作与线程池
线程池类型 Java通过 java.util.concurrent.Executors 的静态方法提供五种线程池 newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需 ...
- 自定义java线程池_我的Java自定义线程池执行器
自定义java线程池 ThreadPoolExecutor是Java并发api添加的一项功能,可以有效地维护和重用线程,因此我们的程序不必担心创建和销毁线程,也不必关注核心功能. 我创建了一个自定义线 ...
- 为什么线程池里的方法会执行两次_面试官问你java都有哪些线程池,自己是否自定义过线程池...
我还记得大学实习面试时,被问到什么是线程池这个问题,因为这个题我被录取了,原因就是我背出来了,而另外一个面试的没背出来,说实话当时还真不知道它是干什么的,就是看面试题给背下来了,在之后就是在实际开发中 ...
- JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理
JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理 参考文章: (1)JAVA线程池ScheduledExecutorServi ...
- springboot如何使用多线程,线程池管理
在原生java中,创建和启动线程的方式大致有以下几种: 继承Thread类,然后重写run方法 实现Runnable接口,并重写run方法 匿名内部类 Thread thread = new Thre ...
- java自定义模拟线程池
java 线程池API提供了newCachedThreadPool() newFixedThreadPool(int) 等方法 1 public static ExecutorService newC ...
- java阻塞线程池_线程池解决阻塞方法
一.序言 当我们需要使用线程的时候,我们可以新建一个线程,然后显式调用线程的start()方法,这样实现起来非常简便,但在某些场景下存在缺陷:如果需要同时执行多个任务(即并发的线程数量很多),频繁地创 ...
- 线程池的参数及执行顺序
线程池的优点 降低系统资源消耗,通过复用已存在的线程,降低线程创建和销毁造成的开销: 提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程创建便立即能够执行. 方便线程并发数的管控, ...
最新文章
- centos7安装mongodb3.4
- Android Studio - HPROF文件查看和分析工具
- Hibernate脏检查的剖析
- 正确退出activity_如何退出Activity
- C语言 exit() _exit()
- js页面传值,cookie
- 苹果计算机系统是什么,苹果电脑系统和Win电脑系统有什么不同
- Pycharm中Python包的下载与使用
- 同一台电脑安装两个版本的jdk和jre
- Linux文件群发脚本
- ARM中C语言和汇编语言互相调用以及实例
- 3.1 数据报表之Excel操作模块 XlsxWriter
- Universal Termsrv.dll Patch 是个好东西
- java 面向对象三大特性之封装 万字详解(超详细)
- Python程序及交通态势数据
- mysql创建数据库(详细)
- K8S ? K3S !
- 魔都记--来美团点评公司快两年的总结
- CSDN访猿团CEO:猿团创业孵化,为何要收26800+10%股权
- java dispo lock_java - 在Java中同步请求响应 - SO中文参考 - www.soinside.com