返回顶部
首页 > 资讯 > 后端开发 > Python >Spring关于@Scheduled限制的问题
  • 783
分享到

Spring关于@Scheduled限制的问题

2024-04-02 19:04:59 783人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录spring @Scheduled限制Spring多定时任务@Scheduled执行阻塞一. 问题描述二. 场景复现三. 解决方案四. 总结Spring @Scheduled限制

Spring @Scheduled限制

@Scheduled具有一定的限制性,它毕竟不是quartz,只是简单的定时,比jdk Timer就加入了线程池而以

  • @Scheduled 不支持年份定时
  • @Scheduled 不支持W L这些字母

没办法 如果非要使用那就只能放弃注解使用XML方式了

Spring多定时任务@Scheduled执行阻塞

一. 问题描述

最近项目中发现一个问题,计划每日凌晨4:40执行一个定时任务,使用注解方式: @Scheduled(cron = “0 40 4 * * ?”),cron表达式明显没有问题,但是这个定时任务总是不按时执行,有时候得等到8点多,有时候9点多才执行。后来查了下,原来这种定时方式默认是单线程执行的,恰好我这里有多个定时任务,并且其中有个在4:40之前的定时任务比较耗时,导致4:40的任务只能等待之前的任务执行完成才能够触发,所以要自己手动把定时任务设置成多线程的方式才行。

二. 场景复现

项目描述:使用SpringBoot进行开发

设置两个定时任务,每5s执行一次,并打印出其执行情况

代码如下:


@Component
@Log4j2
public class ScheduledTask {
    @Scheduled(cron = "0/5 * * * * ?")
    public void task1() throws InterruptedException {
        log.info("I am task11111111, current thread: {}", Thread.currentThread());
        while (true) {
            //模拟耗时任务,阻塞10s
            Thread.sleep(10000);
            break;
        }
    }
    @Scheduled(cron = "0/5 * * * * ?")
    public void task2() {
        log.info("I am task22222222, current thread: {}", Thread.currentThread());
    }
}

执行结果如下:

2019-04-24 17:11:15.008 INFO 16868 --- [ scheduling-1] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:15.009 INFO 16868 --- [ scheduling-1] com.example.demo.task.ScheduledTask : I am task11111111, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:25.009 INFO 16868 --- [ scheduling-1] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:30.002 INFO 16868 --- [ scheduling-1] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:30.003 INFO 16868 --- [ scheduling-1] com.example.demo.task.ScheduledTask : I am task11111111, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:40.004 INFO 16868 --- [ scheduling-1] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[scheduling-1,5,main]

由结果可见,task1与task2由同一个线程Thread[scheduling-1,5,main]执行,也即该定时任务默认使用单线程,并且由于task1阻塞了10s,导致本应5s执行一次的定时任务10s才执行一次。

三. 解决方案

网上有多种解决方案,以下列举两种

方案一:使用@Async注解实现异步任务

这种方式比较简单,在定时任务上加上@Async注解,注意:需启动类配合加上 @EnableAsync才会生效

代码如下:


@Component
@Log4j2
public class ScheduledTask {
    @Async
    @Scheduled(cron = "0/5 * * * * ?")
    public void task1() throws InterruptedException {
        log.info("I am task11111111, current thread: {}", Thread.currentThread());
        while (true) {
            //模拟耗时任务,阻塞10s
            Thread.sleep(10000);
            break;
        }
    }
    @Async
    @Scheduled(cron = "0/5 * * * * ?")
    public void task2() {
        log.info("I am task22222222, current thread: {}", Thread.currentThread());
    }
}

运行结果:

2019-04-24 17:03:00.024 INFO 2152 --- [ task-1] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[task-1,5,main]
2019-04-24 17:03:00.024 INFO 2152 --- [ task-2] com.example.demo.task.ScheduledTask : I am task11111111, current thread: Thread[task-2,5,main]
2019-04-24 17:03:05.001 INFO 2152 --- [ task-3] com.example.demo.task.ScheduledTask : I am task11111111, current thread: Thread[task-3,5,main]
2019-04-24 17:03:05.001 INFO 2152 --- [ task-4] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[task-4,5,main]
2019-04-24 17:03:10.002 INFO 2152 --- [ task-5] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[task-5,5,main]
2019-04-24 17:03:10.003 INFO 2152 --- [ task-6] com.example.demo.task.ScheduledTask : I am task11111111, current thread: Thread[task-6,5,main]

由运行日志可见,定时每5s执行一次已生效,且每次任务使用的线程不一样,也即实现了多线程执行定时任务,不会出现任务等待现象。此方式据说默认线程池大小为100,要是任务不多的话有点大材小用了,所以我觉得第二种方式比较好。

方案二:手动设置定时任务的线程池大小

定时任务代码部分还原,不使用@Async注解,新增启动代码配置:


@Configuration
public class AppConfig implements SchedulinGConfigurer {
    @Bean
    public Executor taskExecutor() {
     //指定定时任务线程数量,可根据需求自行调节
        return Executors.newScheduledThreadPool(3);
    }
    @Override
    public void configureTasks(ScheduledTaskReGIStrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(taskExecutor());
    }
}

运行结果如下:

2019-04-24 17:26:15.008 INFO 2164 --- [pool-1-thread-2] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[pool-1-thread-2,5,main]
2019-04-24 17:26:15.008 INFO 2164 --- [pool-1-thread-1] com.example.demo.task.ScheduledTask : I am task11111111, current thread: Thread[pool-1-thread-1,5,main]
2019-04-24 17:26:20.002 INFO 2164 --- [pool-1-thread-2] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[pool-1-thread-2,5,main]
2019-04-24 17:26:25.001 INFO 2164 --- [pool-1-thread-2] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[pool-1-thread-2,5,main]
2019-04-24 17:26:30.001 INFO 2164 --- [pool-1-thread-1] com.example.demo.task.ScheduledTask : I am task11111111, current thread: Thread[pool-1-thread-1,5,main]
2019-04-24 17:26:30.001 INFO 2164 --- [pool-1-thread-3] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[pool-1-thread-3,5,main]
2019-04-24 17:26:35.001 INFO 2164 --- [pool-1-thread-3] com.example.demo.task.ScheduledTask : I am task22222222, current thread: Thread[pool-1-thread-3,5,main]

由结果可见,第二种方式也实现了多线程任务调度。

四. 总结

两种方式各有优缺点:

比较 方案一 方案二
优点 注解方式使用简单,代码量少 配置灵活,线程数可控
缺点 线程数不可控,可能存在资源浪费 需要增加编码

留个坑,从日志上看@Async方式针对同一任务也是异步的,也即task1每5s会执行一次,但是方式二貌似对同一个任务不会生效,task1执行的时候需等待上一次执行结束才会触发,并没有每5s执行一次。关于这个现象,下次再琢磨…

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Spring关于@Scheduled限制的问题

本文链接: https://lsjlt.com/news/154690.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Spring关于@Scheduled限制的问题
    目录Spring @Scheduled限制Spring多定时任务@Scheduled执行阻塞一. 问题描述二. 场景复现三. 解决方案四. 总结Spring @Scheduled限制...
    99+
    2024-04-02
  • 关于docker cgroups资源限制的问题
    目录一、cpu资源控制1、 设置cpu使用率上限2、设置cpu资源占用比(设置多个容器时才有效)3、设置容器绑定指定的CPU三、内存资源控制四、磁盘IO配额控制1、限制Block I...
    99+
    2024-04-02
  • 关于Spring的问题有哪些
    这篇文章主要讲解了“关于Spring的问题有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“关于Spring的问题有哪些”吧!1 Spring核心组件一句...
    99+
    2024-04-02
  • 关于@Scheduled注解的任务为什么不执行的问题
    目录概述举例说明原因分析解决方案概述 在SpringBoot中可以通过@Scheduled来注解定义一个定时任务,但是有时候你可能发现有的定时任务道理时间却没有执行,但是又不是每次都...
    99+
    2024-04-02
  • 关于Spring Boot动态权限变更问题的实现方案
    1、前言 ​  在Web项目中,权限管理即权限访问控制为网站访问安全提供了保障,并且很多项目使用了Session作为缓存,结合AOP技术进行tok...
    99+
    2024-04-02
  • 关于 Oracle 改错权限问题
    前段时间手残,用exp做数据迁移的时候,因为oracle用户没有目录的写入权限,于是在linux下修改使用 chown -R oracle:oinstall命令修改u01目录下的子目录权限的时候,一不小心直...
    99+
    2024-04-02
  • 关于Spring Boot对jdbc的支持问题
    项目结构 pom.xml pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project x...
    99+
    2024-04-02
  • 关于Spring Ioc和DI注解的问题
    目录1.Spring配置数据源1.1 数据源的开发步骤数据源的手动创建Spring配置数据源抽取jdbc配置文件(最后的方法实现配置数据源)Spring注解开发2 ,Spring新注...
    99+
    2024-04-02
  • 基于Spring Security前后端分离的权限控制系统问题
    目录1. 引入maven依赖2. 建表并生成相应的实体类3. 自定义UserDetails4. 自定义各种Handler5. Token处理6. 访问控制7. 配置WebSecuri...
    99+
    2024-04-02
  • 关于Spring Cloud的熔断器监控问题
    目录Hystrix监控actuator的监控节点集成hystrix dashboard监控详情解读集成Turbine监控参考Hystrix监控 actuator的监控节点 在actu...
    99+
    2024-04-02
  • 关于mysql中root权限丢失的问题
    刚听一哥们说执行了一条语句:revoke all on *.* from root@localhost;            --呵呵,当时到底...
    99+
    2024-04-02
  • 关于Nginx命令行控制的问题
    目录Nginx 介绍1、默认方式启动2、另行指定配置文件的启动方式3、另行指定安装目录的启动方式4、另行指定全局配置项的启动方式5、测试配置信息是否错误6、在测试配置阶段不输出信息7...
    99+
    2022-11-13
    nginx 命令行 nginx 命令行控制
  • 关于spring boot使用 jdbc+mysql 连接的问题
    1.创建文件,勾选JDBC和mysql pom.xml中添加了mysql驱动包和jdbc启动器 2.application.yml添加数据库的配置 spring: dataso...
    99+
    2024-04-02
  • 关于spring aop两种代理混用的问题
    目录spring aop两种代理混用问题一、首先复习一下两种代理二、我们项目是spring-boot项目spring的aop和代理模式理解代理模式代码的主要特点是代理模式目前实现的方...
    99+
    2024-04-02
  • 关于Spring自定义XML schema 扩展的问题(Spring面试高频题)
    引言 自从SpringBoot时代的到来,去除了Spring的各种繁琐的XML配置,让我们可以腾出双手以便于更加专注的搬砖。记得那时候刚学Spring的时候,每天被Spring的各种...
    99+
    2024-04-02
  • 解析spring-security权限控制和校验的问题
    前言     在我们项目中经常会涉及到权限管理,特别是一些企业级后台应用中,那权限管理是必不可少的。这个时候就涉及到技术选型的问题。在...
    99+
    2024-04-02
  • 关于numpy强制类型转换的问题
    目录numpy强制类型转换numpy类型强制转换apinumpy数据类型转换astype,dtype1.查看数据类型2.转换数据类型3.字符串数组转换为数值型numpy强制类型转换 ...
    99+
    2024-04-02
  • 关于上传文件大小受限问题
    一般控制台上会出现像这样   ***1048576 bytes.这大小限制 org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload s...
    99+
    2023-09-30
    java tomcat spring
  • 面试官会问到哪些关于 Spring 同步的问题?
    Spring 是目前最流行的开源框架之一,它提供了丰富的功能和特性,可帮助开发人员更轻松地构建高质量的应用程序。在面试中,面试官经常会问关于 Spring 同步的问题,因此本文将介绍一些常见的问题及其答案。 什么是 Spring 同步? ...
    99+
    2023-09-22
    面试 同步 spring
  • 关于@Scheduled不执行的原因分析
    目录@Scheduled不执行的原因1. 今天用@Schedule做了一个定时任务2. 首先遇到查到的一个解决方案3. 还有版本说要在spring4. 又查到版本说要在Bean上加上...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作