定时任务怎么样避免并发,意思是同一个任务当第一个执行完了,第二才执行,不是一到了间隔时间,不管第一个是否执行完成,第二个就开始执行。

下面小弟整理的笔记

@Scheduled注解是spring boot提供的用于定时任务控制的注解,主要用于控制任务在某个指定时间执行,或者每隔一段时间执行,注意需要配合@EnableScheduling使用,配置@Scheduled主要有三种配置执行时间的方式:cron,fixedRate,fixedDelay

cron

cron是@Scheduled的一个参数,是一个字符串,以空格隔开,允许6或7个域,分别表示秒,分,时,日,月,周,年

表达式就不建议去记怎么玩了,点击去在线生成即可

fixedRate

fixedRate表示自上一次执行时间之后多长时间执行,以ms为单位

fixedDelay

fixedDelay与fixedRate有点类似,不过fixedRate是上一次开始之后计时,fixedDelay是上一次结束之后计时,也就是说,fixedDelay表示上一次执行完毕之后多长时间执行,单位也是ms

initialDelay

initialDelay表示首次延迟多长时间后执行,单位ms,之后按照其他属性指定的规则执行,需要指定别的属性其中一个规则

下面是玩的过程 spring boot项目

正常玩

    @Scheduled(cron = "0/10 * * * * ?")public void cs1(){System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();try {Thread.sleep(60*1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第一个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}@Scheduled(cron = "0/10 * * * * ?")public void cs2(){System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();System.out.println("第二个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}

输出结果

可以看出是单线程环境,但是不满足我要求,然后看到说可以加个注解实现异步

其中一个方法加上@Async启用异步

    @Async@Scheduled(cron = "0/10 * * * * ?")public void cs1(){System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();try {Thread.sleep(60*1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第一个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}@Scheduled(cron = "0/10 * * * * ?")public void cs2(){System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();System.out.println("第二个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}

输出结果

但是这样不行,可能我上个任务数据太多都没执行完成,这也就会导致数据重复消费了,不科学,继续找

网上找了一下,好多地方都推荐这两个属性fixedDelay 和 fixedRate,分别干啥上面写了

fixedRate走一波

    @Async@Scheduled(fixedRate = 1000*10)public void cs1(){System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();try {Thread.sleep(60*1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第一个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}@Scheduled(cron = "0/10 * * * * ?")public void cs2(){System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();System.out.println("第二个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}

输出结果

假装有图,结果同上,不管执行不,到点就执行

fixedDelay走一波

是否可以就看这个了,毕竟fixedDelay这个属性表示上一次执行完毕之后多长时间执行,看字面意思,结束了,才会执行下一次,心心念念的走一波

    @Async@Scheduled(fixedDelay = 1000*10)public void cs1(){System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();try {Thread.sleep(60*1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第一个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}@Scheduled(cron = "0/10 * * * * ?")public void cs2(){System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();System.out.println("第二个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}

见证奇迹的输出结果

假装有结果吧,我都不想看

结论

  • spring 是单线程的,不管多少个任务都是一个线程再跑
  • 某个方法使用注解 @Async,开启异步执行,那个其他定时任务依然遵循上个结论,使用了@Async这个注解的会多个线程执行,不管选择 cron,fixedRate,fixedDelay这三里的谁都一样

问题

  • 只有一个任务单独执行,其他任务依然共用一个线程
  • 单独执行的这个任务,需要操作数据库,所以只能一个时间只能有一个线程在执行
  • 这个定时任务,每分钟执行一次,大多数时候没有数据操作
  • 有数据的时候,一般执行三到五分钟

所以问题来了,每分钟执行一次,有数据的时候,此任务没有执行完成,单线程的时候,会被其他定时任务阻塞,针对这个定时任务,开启异步处理,那此任务就会在没有执行完成的时候,下个一分钟间隔到来前又执行一次

咋整!!咋整!!咋整!!!!!

上面已解决

代码

    @Async@Scheduled(cron = "0/10 * * * * ?")public void cs1(){if (i == 1){i++;System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();try {Thread.sleep(60*1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第一个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();i--;}else {System.out.println("定时任务未执行" + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());}}//    @Async@Scheduled(cron = "0/10 * * * * ?")public void cs2(){System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();System.out.println("第二个定时任务结束 : " + LocalDateTime.now().toLocalTime() +"\r\n线程 : " + Thread.currentThread().getName());System.out.println();}

输出结果

现在有个小问题

到时间之后定时任务是另外一个线程在执行,但是我没有弄线程池,代码里面也并没有Thread.sleep(60*1000)这种线程相关的代码,那么到时候新开的线程是怎么样的,对线程理解有点弱,如果按照这种写法会不会有问题,有问题是什么样的问题

【问题】定时任务整理笔记附问题求大佬解答!!!!相关推荐

  1. 用python求两个人的平均身高_大学python题 求大佬解答!!!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 7-4 计算指数 (5 分) 真的没骗你,这道才是简单题 -- 对任意给定的不超过10的正整数n,要求你输出2n.不难吧? 输入格式: 输入在一行中给出一 ...

  2. 大学python编程题_大学python题 求大佬解答!!!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 7-4 计算指数 (5 分) 真的没骗你,这道才是简单题 -- 对任意给定的不超过10的正整数n,要求你输出2n.不难吧? 输入格式: 输入在一行中给出一 ...

  3. 美团笔试题2021.8.29(第四题求大佬解答)

    美团笔试题2021.8.29 又再帮同学写,推了这周的周赛,侥幸都有点思路 丁香树 题目描述 思路 因为芳香值最大为30,所以用一个数组存储已走过的芳香值,然后走到第i个点,找比当前芳香值小的有多少个 ...

  4. python求二叉树高度_求二叉树高度代码报错,求大佬解答

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 代码如下 class BTree(object): def __init__(self, data=None, left=None, right=None ...

  5. python 10053_python 写的selenium脚本不能循环,循环时会报 [WinError 10053] 你的主机中的软件中止了一个已建立的连接。错误,求大佬解答下...

    用python写了一段自动化脚本,在循环的时候报ConnectionAbortedError: [WinError 10053] 你的主机中的软件中止了一个已建立的连接.错误,第一次执行没有问题,就是 ...

  6. c语言链表萌新,萌新一枚,关于链表问题求大佬解答

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 代码如下 #include #include #include struct student { int num; float score; struct ...

  7. 有没有检查c语言编译错误的软件,求大佬解答,为什么这个程序编译软件检查不出错误...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include /* malloc()等 */ #include #include #include /* exit() */ #de ...

  8. exchange邮箱一直提示密码错误,密码是正确的,求大佬解答

  9. 做ctf题目的时候运行程序就会显示ImportError: cannot import name ‘flag‘ from ‘secret‘ 求大佬解答

最新文章

  1. matlab数据可视化总结,机器学习----Matlab数据可视化总结(plot篇)
  2. 京东智能情感客服挽救一名学生生命,“可信赖的AI”用温暖前行
  3. python编写圣诞树代码_python 实现圣诞树
  4. Android开发之http网络请求返回码问题集合。
  5. Django 多数据库联用(看着不错还有源码可以下载)
  6. JavaScript:动态选中CheckBox
  7. Linux基础命令---文本过滤colrm
  8. js 求时间差 字符串转化为日期
  9. 操作系统ppt_华为车BU王军:华为三大汽车操作系统,及跨域集成软件框架(内含PPT)...
  10. 如何在无显示器的ubuntu下跑selenium
  11. 如何攻克 Android 调试难题?| 技术头条
  12. Javaweb中上传图片,获取相对路径,绝对路径
  13. 有什么哪些便宜的云服务器推荐?
  14. 使用codemirror打造你自己的前端在线编辑器
  15. 编程爱好者网站试题中心 的一道题:关于*(p++)
  16. 解决 ffmpeg yasm not found, use --disable-yasm for a crippled build
  17. 丁达尔效应产生的原因_详细解读什么是丁达尔现象
  18. 6-RabbitMQ实战
  19. 微信小程序开发SSM投票系统+后台管理系统|前后分离VUE
  20. 振动力学——2.单自由度系统无阻尼自由振动能量法

热门文章

  1. 图像处理之一阶微分应用
  2. Asp.net MVC防止图片盗链的实现方法,通过自定义RouteHandler来操作
  3. 由浅入深:自己动手开发模板引擎——置换型模板引擎(一)
  4. JavaScript(19)jQuery HTML 获取和设置内容和属性
  5. js获取和设置属性的方法
  6. 后缀数组--处理字符串的利器
  7. 搭建kubernetes DashBoard
  8. STM32中FLASH_Status的5个状态各表示的含义详解
  9. IP地址的分类及各类IP的最大网络数、网络号范围和最大主机数
  10. 【自由随想录(一)】