专栏首页java系列博客spring boot默认单线程排队跑定时任务问题记录

spring boot默认单线程排队跑定时任务问题记录

作者:小小明童鞋

链接:https://my.oschina.net/xiaomingnevermind/blog/3143095

问题描述:在使用springboot默认的定时任务时,若存在多个任务,框架默认只启动一个线程执行,会导致有些任务不能在指定时间开始执行

另,关于分布式下定时任务同步锁问题,会再单独写一篇记录

测试默认情况下定时任务的线程名称:

package com.example.demo.job;

import net.javacrumbs.shedlock.core.SchedulerLock;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
@EnableScheduling
public class TestJob {


    @Scheduled(cron = "0/5 * * * * ?")
    @SchedulerLock(name = "test1-task", lockAtMostForString = "PT28M", lockAtLeastForString = "PT28M")
    public void execute1() {
        String curName = Thread.currentThread().getName();
        System.out.println("当前时间:" + LocalDateTime.now() + "  任务execute1对应的线程名: " + curName);
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Scheduled(cron = "0/5 * * * * ?")
    @SchedulerLock(name = "test2-task", lockAtMostForString = "PT28M", lockAtLeastForString = "PT28M")
    public void execute2() {

        String curName = Thread.currentThread().getName();
        System.out.println("当前时间:" + LocalDateTime.now() + "  任务execute2对应的线程名: " + curName);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/10 * * * * ?")
    @SchedulerLock(name = "test3-task", lockAtMostForString = "PT28M", lockAtLeastForString = "PT28M")
    public void execute3() {

        String curName = Thread.currentThread().getName();
        System.out.println("当前时间:" + LocalDateTime.now() + "  任务execute3对应的线程名: " + curName);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

结果如下:

spring boot 自带的定时任务默认只起一个线程:

这种情况下,对于有些定时任务若设定在某一固定时刻开始执行,就可能出现需要排队而不能准时执行的情况。然后找了下解决方案,我不太想巴拉源码了,网上大家都扒出来了,就是为空初始化一个线程那段,直接点上解决方案:

在启动类里面加上如下代码:

/**
	 *  解决定时任务单线程排队问题,建立线程池
	 * @return
	 */
	@Bean
	public TaskScheduler taskScheduler() {
		ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
		taskScheduler.initialize();
		taskScheduler.setPoolSize(50);
		return taskScheduler;
	}

然后重新启动看下线程的情况:

以及核心线程数:

这样就解决了单线程问题。

另:分布式情况下只能有一个定时任务在执行,防止重复执行的方案有很多,下次再写。

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:https://my.oschina.net/xiaomingnevermind/blog复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 玩转 Spring Boot 入门篇

    Spring 颠覆了 Java 企业级项目的开发,使得企业级的开发由重变轻、由繁至简,可谓是为 Java 程序员带来了春天。

    一猿小讲
  • 玩转 Spring Boot 集成篇(@Scheduled、静态、动态定时任务)

    研发说:API 请求量到底啥情况呀?统计发粗来(万一访问量一直激增,导致服务宕了,要扣我绩效滴)。

    一猿小讲
  • Spring Boot 2.x中如何使用Log4j2记录日志

    上一篇我们介绍了Spring Boot 2.x中默认日志框架Logback的使用。今天继续说说日志,接下来我们要讲是前段时间爆出核弹漏洞的Log4j2。虽然出了...

    程序猿DD
  • 重学SpringBoot系列之嵌入式容器的配置与应用

    在Spring Boot项目中,可以支持Tomcat、Jetty、Undertow的Web应用服务容器。当我们添加了spring-boot-starter-we...

    大忽悠爱学习
  • Spring Boot 最流行的 16 条最佳实践!

    Spring Boot是最流行的用于开发微服务的Java框架。在本文中,我将与你分享自2016年以来我在专业开发中使用Spring Boot所采用的最佳实践。这...

    搜云库
  • 2017年终总结

    又到了写年终总结的时候了。每当这个时候思绪总是翻江倒海,因为太久没有反思和总结的缘故,一年才总结一次,确实是有点久,欠的账的太多,梳理起来有点费劲。这里依旧还是...

    code4it
  • Sentinel

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

    大忽悠爱学习
  • Spring Boot 多个定时器冲突,怎么解决?

    点击关注公众号,Java干货及时送达 战术分析 上次的博客疏忽了定时器的一个大重点… 实际开发项目中一定不止一个定时器,很多场景都需要用到,而多个定时器带来...

    Java技术栈
  • Apache Log4j2详解

    在项目开发中,都不可避免的使用到日志。没有日志虽然不会影响项目的正确运行,但是没有日志的项目可...

    Java架构师必看
  • Spring Boot 最流行的 16 条实践解读!

    Spring Boot是最流行的用于开发微服务的Java框架。在本文中,我将与你分享自2016年以来我在专业开发中使用Spring Boot所采用的最佳实践。这...

    周三不加班
  • 快速组建Java项目持续集成环境

    2014年时在这里就写过一篇关于持续集成的文章[Jenkins 使用教程]当时的Jenkins还是1.x版本,没想到5年过去了都9102年了,今天和朋友聊天还有...

    海哥@开发
  • Spring Boot 2.3.0正式发布:优雅停机、配置文件位置通配符新特性一览

    各位小伙伴大家好,我是A哥。北京时间2020-05-15,Spring Boot 2.3.0版本正式发布了,次版本号的升级,一般会有些新特性出来。作为Java ...

    YourBatman
  • Spring 异步调用,一行代码实现!舒服,不接受任何反驳~

    在日常开发中,我们的逻辑都是同步调用,顺序执行。在一些场景下,我们会希望异步调用,将和主线程关联度低的逻辑异步调用,以实现让主线程更快的执行完成,提升性能。例如...

    芋道源码
  • 重学SpringBoot系列之日志框架与全局日志管理

    日志门面(SLF4J)主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架来实现,例如log4j和...

    大忽悠爱学习
  • Spring Cloud Alibaba之服务容错组件 - Sentinel Dashboard控制台(十二)

    上一篇文章我们已经对 Sentinel 有个简单的了解,接下来我们将讲解 Sentinel的具体使用。 Sentinel的使用分为两部分:

    用户1212940
  • Java 工程师成神之路 | 2019正式版

    JVM 还支持哪些语言(Kotlin、Groovy、JRuby、Jython、Scala)

    乔戈里
  • 2019年Java工程师成神之路正式版

    你是否想让自己的Java知识更上一层呢?是否想成为Java工程师大神呢?下面将告诉你如何成神之路,让自己更牛逼!

    格姗知识圈
  • 什么鬼,面试官竟然让敖丙用Redis实现一个消息队列!!?

    众所周知,redis是一个高性能的分布式key-value存储系统,在NoSQL数据库市场上,redis自己就占据了将近半壁江山,足以见到其强大之处。同时,由于...

    敖丙
  • 面试官竟让我用Redis实现一个消息队列!

    众所周知,redis是一个高性能的分布式key-value存储系统,在NoSQL数据库市场上,redis自己就占据了将近半壁江山,足以见到其强大之处。同时,由...

    数据和云

扫码关注云+社区

领取腾讯云代金券