Spring boot如何通过@Scheduled实现定时任务及多线程配置
这篇文章主要介绍了Springboot如何通过@Scheduled实现定时任务及多线程配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
使用@Scheduled可以很容易实现定时任务
springboot的版本2.1.6.RELEASE
packagecom.abc.demo.common; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.scheduling.annotation.EnableScheduling; importorg.springframework.scheduling.annotation.Scheduled; importorg.springframework.stereotype.Component; importjava.text.SimpleDateFormat; importjava.util.concurrent.TimeUnit; @EnableScheduling @Component publicclassScheduleSetting{ privatefinalLoggerlogger=LoggerFactory.getLogger(Tasks.class); @Scheduled(fixedRate=10000,initialDelay=2000) publicvoidscheduleRead(){ try{ longtimeStamp=System.currentTimeMillis(); SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss"); Threadthread=Thread.currentThread(); System.out.println("cron1任务开始,start="+simpleDateFormat.format(timeStamp)+",threadId="+thread.getId()+",threadName="+thread.getName()); longendStamp=System.currentTimeMillis(); try{ TimeUnit.SECONDS.sleep(20); }catch(InterruptedExceptione){ e.printStackTrace(); } System.out.println("cron1任务正在运行的线程名称:"+thread.getName()+"结束,start="+simpleDateFormat.format(timeStamp)+",end="+simpleDateFormat.format(endStamp)); System.out.println("++++++++++++++++++++++++"); }catch(Exceptione){ logger.error(e.getMessage()); } } @Scheduled(fixedRate=5000,initialDelay=1000) publicvoidscheduleConvert(){ try{ longtimeStamp=System.currentTimeMillis(); SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss"); Threadthread=Thread.currentThread(); System.out.println("cron2任务开始,start="+simpleDateFormat.format(timeStamp)+",threadId="+thread.getId()+",threadName="+thread.getName()); try{ TimeUnit.SECONDS.sleep(10); }catch(InterruptedExceptione){ e.printStackTrace(); } longendStamp=System.currentTimeMillis(); System.out.println("cron2任务正在运行的线程名称:"+thread.getName()+"结束,start="+simpleDateFormat.format(timeStamp)+",end="+simpleDateFormat.format(endStamp)); System.out.println("===================="); }catch(Exceptione){ logger.error(e.getMessage()); } } }
运行输出内容为
cron2任务开始,start=2019-10-1117:31:52,threadId=34,threadName=scheduling-1 cron2任务正在运行的线程名称:scheduling-1结束,start=2019-10-1117:31:52,end=2019-10-1117:32:02 ==================== cron1任务开始,start=2019-10-1117:32:02,threadId=34,threadName=scheduling-1 cron1任务正在运行的线程名称:scheduling-1结束,start=2019-10-1117:32:02,end=2019-10-1117:32:02 ++++++++++++++++++++++++ cron2任务开始,start=2019-10-1117:32:22,threadId=34,threadName=scheduling-1 cron2任务正在运行的线程名称:scheduling-1结束,start=2019-10-1117:32:22,end=2019-10-1117:32:32 ……
注:
cron2执行完后才会执行cron1
原因:
spring默认是以单线程执行任务调度
spring的定时任务默认最大运行线程数为1,多个任务执行起来时间会有问题
1.配置线程池
在配置文件application.properties中添加
#线程池大小 spring.task.scheduling.pool.size=5 #线程名前缀 spring.task.scheduling.thread-name-prefix=myScheduling-
输出内容变为
cron2任务开始,start=2019-10-1117:34:48,threadId=34,threadName=myScheduling-1 cron1任务开始,start=2019-10-1117:34:49,threadId=35,threadName=myScheduling-2 cron2任务正在运行的线程名称:myScheduling-1结束,start=2019-10-1117:34:48,end=2019-10-1117:34:58 ==================== cron2任务开始,start=2019-10-1117:34:58,threadId=34,threadName=myScheduling-1 cron2任务正在运行的线程名称:myScheduling-1结束,start=2019-10-1117:34:58,end=2019-10-1117:35:08 ==================== cron2任务开始,start=2019-10-1117:35:08,threadId=57,threadName=myScheduling-3 cron1任务正在运行的线程名称:myScheduling-2结束,start=2019-10-1117:34:49,end=2019-10-1117:34:49 ……
注:
多线程下,cron1和cron2不用互相等待了,但是同一个任务还是需要等待的
2.并发
修改代码
packagecom.abc.demo.common; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.scheduling.annotation.Async; importorg.springframework.scheduling.annotation.EnableAsync; importorg.springframework.scheduling.annotation.EnableScheduling; importorg.springframework.scheduling.annotation.Scheduled; importorg.springframework.stereotype.Component; importjava.text.SimpleDateFormat; importjava.util.concurrent.TimeUnit; @EnableScheduling @Component @EnableAsync publicclassScheduleSetting{ privatefinalLoggerlogger=LoggerFactory.getLogger(Tasks.class); @Async @Scheduled(fixedRate=10000,initialDelay=2000) publicvoidscheduleRead(){ try{ longtimeStamp=System.currentTimeMillis(); SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss"); Threadthread=Thread.currentThread(); System.out.println("cron1任务开始,start="+simpleDateFormat.format(timeStamp)+",threadId="+thread.getId()+",threadName="+thread.getName()); longendStamp=System.currentTimeMillis(); try{ TimeUnit.SECONDS.sleep(20); }catch(InterruptedExceptione){ e.printStackTrace(); } System.out.println("cron1任务正在运行的线程名称:"+thread.getName()+"结束,start="+simpleDateFormat.format(timeStamp)+",end="+simpleDateFormat.format(endStamp)); System.out.println("++++++++++++++++++++++++"); }catch(Exceptione){ logger.error(e.getMessage()); } } @Async @Scheduled(fixedRate=5000,initialDelay=1000) publicvoidscheduleConvert(){ try{ longtimeStamp=System.currentTimeMillis(); SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss"); Threadthread=Thread.currentThread(); System.out.println("cron2任务开始,start="+simpleDateFormat.format(timeStamp)+",threadId="+thread.getId()+",threadName="+thread.getName()); try{ TimeUnit.SECONDS.sleep(10); }catch(InterruptedExceptione){ e.printStackTrace(); } longendStamp=System.currentTimeMillis(); System.out.println("cron2任务正在运行的线程名称:"+thread.getName()+"结束,start="+simpleDateFormat.format(timeStamp)+",end="+simpleDateFormat.format(endStamp)); System.out.println("===================="); }catch(Exceptione){ logger.error(e.getMessage()); } } }
输出的内容
cron2任务开始,start=2019-10-1117:39:53,threadId=57,threadName=task-1 cron1任务开始,start=2019-10-1117:39:54,threadId=59,threadName=task-2 cron2任务开始,start=2019-10-1117:39:58,threadId=61,threadName=task-3 cron2任务开始,start=2019-10-1117:40:03,threadId=63,threadName=task-4 cron2任务正在运行的线程名称:task-1结束,start=2019-10-1117:39:53,end=2019-10-1117:40:03 ==================== cron1任务开始,start=2019-10-1117:40:04,threadId=64,threadName=task-5 cron2任务开始,start=2019-10-1117:40:08,threadId=65,threadName=task-6 cron2任务正在运行的线程名称:task-3结束,start=2019-10-1117:39:58,end=2019-10-1117:40:08 ==================== cron2任务开始,start=2019-10-1117:40:13,threadId=66,threadName=task-7 cron2任务正在运行的线程名称:task-4结束,start=2019-10-1117:40:03,end=2019-10-1117:40:13 ==================== cron1任务正在运行的线程名称:task-2结束,start=2019-10-1117:39:54,end=2019-10-1117:39:54
说明:
- @EnableAsync开启多线程
- @Async标记其为一个异步任务
- 每个定时任务都是在通过不同的线程来处理,线程名的前缀成了task-
- 线程默认为10个
修改配置
spring.task.execution.thread-name-prefix=mytask- spring.task.execution.pool.core-size=5
重新运行的输出
cron2任务开始,start=2019-10-1117:44:00,threadId=56,threadName=mytask-1 cron1任务开始,start=2019-10-1117:44:01,threadId=57,threadName=mytask-2 cron2任务开始,start=2019-10-1117:44:05,threadId=58,threadName=mytask-3 cron2任务开始,start=2019-10-1117:44:10,threadId=59,threadName=mytask-4 cron2任务正在运行的线程名称:mytask-1结束,start=2019-10-1117:44:00,end=2019-10-1117:44:10 ==================== cron1任务开始,start=2019-10-1117:44:11,threadId=60,threadName=mytask-5 cron2任务正在运行的线程名称:mytask-3结束,start=2019-10-1117:44:05,end=2019-10-1117:44:15 ==================== cron2任务开始,start=2019-10-1117:44:15,threadId=58,threadName=mytask-3 cron2任务开始,start=2019-10-1117:44:20,threadId=56,threadName=mytask-1 cron2任务正在运行的线程名称:mytask-4结束,start=2019-10-1117:44:10,end=2019-10-1117:44:20 ==================== cron1任务正在运行的线程名称:mytask-2结束,start=2019-10-1117:44:01,end=2019-10-1117:44:01
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。