前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring boot默认单线程排队跑定时任务问题记录

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

作者头像
小小明童鞋
发布2019-12-15 20:33:54
1.8K0
发布2019-12-15 20:33:54
举报

作者:小小明童鞋

链接:https://cloud.tencent.com/developer/article/1554026

问题描述:在使用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;
	}

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

以及核心线程数:

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档