[线程池]Springboot如何使用线程池
本文带你快速了解@Async注解的用法,包括异步方法无返回值、有返回值,最后总结了@Async注解失效的几个坑。
在 SpringBoot 应用中,经常会遇到在一个接口中,同时做事情1,事情2,事情3,如果同步执行的话,则本次接口时间取决于事情1 2 3执行时间之和;如果三件事同时执行,则本次接口时间取决于事情1 2 3执行时间最长的那个,合理使用多线程,可以大大缩短接口时间。那么在 SpringBoot 应用中如何优雅的使用多线程呢?
(资料图)
Don"t bb, show me code.
快速使用
SpringBoot应用中需要添加@EnableAsync
注解,来开启异步调用,一般还会配置一个线程池,异步的方法交给特定的线程池完成,如下:
@Configuration@EnableAsyncpublic class AsyncConfiguration { @Bean("doSomethingExecutor") public Executor doSomethingExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 核心线程数:线程池创建时候初始化的线程数 executor.setCorePoolSize(10); // 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程 executor.setMaxPoolSize(20); // 缓冲队列:用来缓冲执行任务的队列 executor.setQueueCapacity(500); // 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁 executor.setKeepAliveSeconds(60); // 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池 executor.setThreadNamePrefix("do-something-"); // 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程) executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); executor.initialize(); return executor; }}
使用的方式非常简单,在需要异步的方法上加@Async
注解
@RestControllerpublic class AsyncController { @Autowired private AsyncService asyncService; @GetMapping("/open/something") public String something() { int count = 10; for (int i = 0; i < count; i++) { asyncService.doSomething("index = " + i); } lon return "success"; }}@Slf4j@Servicepublic class AsyncService { // 指定使用beanname为doSomethingExecutor的线程池 @Async("doSomethingExecutor") public String doSomething(String message) { log.info("do something, message={}", message); try { Thread.sleep(1000); } catch (InterruptedException e) { log.error("do something error: ", e); } return message; }}
访问:127.0.0.1:8080/open/something,日志如下
2020-04-19 23:42:42.486 INFO 21168 --- [io-8200-exec-17] x.g.b.system.controller.AsyncController : do something end, time 8 milliseconds2020-04-19 23:42:42.488 INFO 21168 --- [ do-something-1] x.gits.boot.system.service.AsyncService : do something, message=index = 02020-04-19 23:42:42.488 INFO 21168 --- [ do-something-5] x.gits.boot.system.service.AsyncService : do something, message=index = 42020-04-19 23:42:42.488 INFO 21168 --- [ do-something-4] x.gits.boot.system.service.AsyncService : do something, message=index = 32020-04-19 23:42:42.488 INFO 21168 --- [ do-something-6] x.gits.boot.system.service.AsyncService : do something, message=index = 52020-04-19 23:42:42.488 INFO 21168 --- [ do-something-9] x.gits.boot.system.service.AsyncService : do something, message=index = 82020-04-19 23:42:42.488 INFO 21168 --- [ do-something-8] x.gits.boot.system.service.AsyncService : do something, message=index = 72020-04-19 23:42:42.488 INFO 21168 --- [do-something-10] x.gits.boot.system.service.AsyncService : do something, message=index = 92020-04-19 23:42:42.488 INFO 21168 --- [ do-something-7] x.gits.boot.system.service.AsyncService : do something, message=index = 62020-04-19 23:42:42.488 INFO 21168 --- [ do-something-2] x.gits.boot.system.service.AsyncService : do something, message=index = 12020-04-19 23:42:42.488 INFO 21168 --- [ do-something-3] x.gits.boot.system.service.AsyncService : do something, message=index = 2
由此可见已经达到异步执行的效果了,并且使用到了咱们配置的线程池。
获取异步方法返回值
当异步方法有返回值时,如何获取异步方法执行的返回结果呢?这时需要异步调用的方法带有返回值CompletableFuture。
CompletableFuture是对Feature的增强,Feature只能处理简单的异步任务,而CompletableFuture可以将多个异步任务进行复杂的组合。如下:
@RestControllerpublic class AsyncController { @Autowired private AsyncService asyncService; @SneakyThrows @ApiOperation("异步 有返回值") @GetMapping("/open/somethings") public String somethings() { CompletableFuture createOrder = asyncService.doSomething1("create order"); CompletableFuture reduceAccount = asyncService.doSomething2("reduce account"); CompletableFuture saveLog = asyncService.doSomething3("save log"); // 等待所有任务都执行完 CompletableFuture.allOf(createOrder, reduceAccount, saveLog).join(); // 获取每个任务的返回结果 String result = createOrder.get() + reduceAccount.get() + saveLog.get(); return result; }}@Slf4j@Servicepublic class AsyncService { @Async("doSomethingExecutor") public CompletableFuture doSomething1(String message) throws InterruptedException { log.info("do something1: {}", message); Thread.sleep(1000); return CompletableFuture.completedFuture("do something1: " + message); } @Async("doSomethingExecutor") public CompletableFuture doSomething2(String message) throws InterruptedException { log.info("do something2: {}", message); Thread.sleep(1000); return CompletableFuture.completedFuture("; do something2: " + message); } @Async("doSomethingExecutor") public CompletableFuture doSomething3(String message) throws InterruptedException { log.info("do something3: {}", message); Thread.sleep(1000); return CompletableFuture.completedFuture("; do something3: " + message); }}
访问接口
C:\Users\Administrator>curl -X GET "http://localhost:8200/open/somethings" -H "accept: */*"do something1: create order; do something2: reduce account; do something3: save log
控制台上关键日志如下:
2020-04-20 00:27:42.238 INFO 5672 --- [ do-something-3] x.gits.boot.system.service.AsyncService : do something3: save log2020-04-20 00:27:42.238 INFO 5672 --- [ do-something-2] x.gits.boot.system.service.AsyncService : do something2: reduce account2020-04-20 00:27:42.238 INFO 5672 --- [ do-something-1] x.gits.boot.system.service.AsyncService : do something1: create order
注意事项
@Async
注解会在以下几个场景失效,也就是说明明使用了@Async
注解,但就没有走多线程。
@Component
和@Service
,并且能被Spring扫描到);SpringBoot应用中没有添加@EnableAsync
注解;在同一个类中,一个方法调用另外一个有@Async注解的方法,注解不会生效。原因是@Async注解的方法,是在代理类中执行的。通过上边几个示例,@Async实际还是通过Future或CompletableFuture来异步执行的,Spring又封装了一下,让我们使用的更方便。
-
[线程池]Springboot如何使用线程池在SpringBoot应用中,经常会遇到在一个接口中,同时做事情1,事情2,事情3,如果同步执行的话,则本次接口时间取决于事情123执行时间之和;如果三
-
世界热讯:脓胸1、脓胸是由病菌侵入胸膜腔,产生脓性渗出液积聚于胸膜腔内的化脓性感染。2、脓胸多发于青壮年。3、脓胸可分为急性和慢性。4
-
每日聚焦:发热膜是什么东西_发热膜1、electricradiantheatingfilm工作时将电能转化为热能。2、并将热能主要以辐射的形式向外传
-
形位公差的标注方法有_形位公差的标注方法1、形位公差的标注应注意以下问题:(1)形位公差内容用框格表示,框格内容自左向右第一格总是形位公差项目符号,第二格为公差
-
滚动:信用卡 怎么取现_信用卡取现技巧1、可以通过ATM机取现。2、用卡取现分为两种情况:情况一:信用卡透支取现,也就是说我们取出来的钱是通过透支取现的方式进
-
今日圣诞老人的做法 纸折_DIY折纸教程之圣诞老人1、首先准备一张正方形纸,然后分别沿对角线折叠出两条痕迹,如图所示。2、打开白色这一面,选择正方形的一个顶点朝中心折叠,
-
蜀道难是什么时候学的_sdn是什么 世界热头条今天小编肥嘟来为大家解答以上的问题。蜀道难是什么时候学的,sdn是什么相信很多小伙伴还不知道,现在让我们一起来看看吧!1、SDN最简单的意思
-
“硅谷银行”不是第一张骨牌-天天快看近期美国金融业负面新闻频发,上周管理资产规模高达9510亿美元的全球最大另类资产管理公司、私募股权巨头黑石集团违约一只5 31亿欧元的芬兰商
-
神宇股份:公司产品有海外出口 海外业务占比不大 天天新视野每经AI快讯,有投资者在投资者互动平台提问:请问董秘,公司产品是否出口到海外,海外业务占比是多少神宇股份(300563 SZ)3月16日在投资者互动
-
斑竹又名_ldquo 斑竹 rdquo 是什么典故1、传说,舜帝的二个妃子娥皇女英千里寻追舜帝。2、到君山后,闻舜帝已崩,抱竹痛哭,流泪成血,落在竹子形成斑点,故又名“泪
-
深化“林长+警长”协作机制 福建省首个野生动物救助保护基地揭牌深化“林长+警长”协作机制福建省首个野生动物救助保护基地揭牌
-
乐享研学之旅|世界最资讯本报讯(YMG全媒体记者何晓波通讯员林君摄影报道)春暖花开,来一场植物园“研学之旅”。3月11日下午,烟台金心公益团队志愿者们来到烟台植...
-
全球观热点:合肥轨道三号线站点名称_合肥轨道交通3号线站点1、如下:合肥轨道交通3号线(HefeiMetroLine3),是中国安徽省合肥市一条正在建设的地铁线路,预计一
-
哑口无言的反义词_哑口无言 天天即时1、释义:哑口:像哑巴一样。2、像哑巴一样说不出话。3、形容理屈词穷一时语塞或紧张。4、哑口无言:汉语成语。5、拼音:y
-
【播资讯】图片报:哈维-阿隆索是皇马主帅候选人之一德国《图片报》报道,哈维-阿隆索是皇马新帅候选。虽然安切洛蒂上赛季带皇马赢得欧冠和西甲,但本赛季球队在西甲表现不佳,导致他处于压力之下
-
os是什么意思中文_os是什么意思1、OS意思是操作系统,时OperatingSystem的简写,一般指操作系统(计算机管理控制程序)。2、OS是管理计
-
今日爱的华尔兹是什么歌(爱的华尔兹歌词 坐等)-资讯推荐爱的华尔兹是什么歌,爱的华尔兹歌词坐等很多人还不知道,现在让我们一起来看看吧!1、爱的华尔兹-郑爽词:严丹丹曲:刘佳踮起脚尖提起裙边让
-
厦门市医疗保险缴费基数2023 本市户籍外来人员缴费比例一样吗?_焦点热文厦门市医疗保险缴费基数2023本市户籍外来人员缴费比例多少?下面同社保网小编来看看。2023年1月起,放开灵活就业人员参加职工医保的户籍限制,
-
2022-2023开封祥符区停暖通知 环球动态开封市祥符区集中供热延长至3月19日零时!尊敬的热用户:根据《开封市集中供热管理办法》第十八条规定,我市集中供热结束时间为3月15日前后,
-
白酒新物种肆拾玖坊怎么样,值得大众收藏吗?|时讯近年来,以茅台酒为首的酱香型白酒很受大众喜爱,让不少人看到了其收藏价值,从而引发酱酒热潮。作为白酒新物种的肆拾玖坊也收获不少消费者关注,
-
天天微速讯:异动快报:国统股份(002205)3月15日10点46分触及涨停板3月15日盘中消息,10点46分国统股份(002205)触及涨停板。目前价格12 67,上涨9 98%。其所属行业装修建材目前上涨。领涨股为国统股份。该股为
-
进不了大三甲,回不去小县城,985医学毕业生“被出局”考上复旦大学医学院,并没让王河(化名)开心。学临床医学的王河是上海本地人,今年考研二战成绩不理想,正等待调剂或转行。咖啡
-
每日资讯:写给父亲的最感动话短句子(写给父亲催泪的话简短)父爱是金色的阳光,总能照亮我的世界;父爱是流动的河流,总能滋润我的心田;父爱是一座挺拔的山,可以一直支撑我的一生。以下是
-
歌曲妻子原唱是谁_歌曲妻子原唱 环球热点1、妻子歌原唱谭晶。2、歌词:这些年的不容易我怎能告诉你有过多少叹息也有多少挺立长夜的那串泪滴我怎能留给你有过多少憔悴也
-
当前消息!领克汽车:2022年年全年海外出运量35588辆领克汽车官博1月9日消息,2022年领克全年海外出运量35588辆,其中新能源占比97%。
-
正规抵押车平台有哪些?盘点六个安全可靠的贷款平台想要办理抵押车贷款,客户能不能找到正规的贷款平台很重要,对于大部分客户来说,因为市场上为自己提供贷款服务的平台有很多,想
-
唐源电气(300789)3月14日主力资金净卖出61.59万元截至2023年3月14日收盘,唐源电气(300789)报收于24 53元,下跌1 6%,换手率1 44%,成交量7879 0手,成交额1926 46万元。
-
javbus新地址_世界头条1、链接:u点O这l进b入O将sin^2(8x)用三角恒等式降幂后。2、可以用tabularmethod直接计算得:∫
-
人际交往中的公共关系主要体现在_ _人际交往中的公共关系主要体现在1、人际关系之目标乃是要建立幸福人生、和谐组织、安定社会与世界大同。2、步骤:建立良好人际关系须从个人品德修养做起,按部
-
慈利:油菜花开春意浓 乡村美景入画来 世界观速讯红网时刻记者全江玲通讯员黄岳云严德群联合报道春光明媚,万物复苏。近日,在慈利县广袤的田地里油菜花竞相开放,金灿