时讯:[线程池]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执行时间之和;如果三 -
天天微动态丨快讯:南方路机涨停 报于28.81元金融界3月17日消息今日南方路机(行情603280,诊股)开盘报26 08元,截止09:52分,该股涨10%报28 81元,封上涨停板。昨日(2023-03 -
焦点快看:综合评价招生(什么是综合评价招生)1、高职分类考试招生是普通高等教育考试招生(含高职分类考试招生和普通高校统一考试招生)的重要组成部分,该考试属国家教育考试。2、通过高 -
世界速读:广西来宾市忠良乡中心校1、忠良乡中心校建于1954年,2001年建成国家希望小学。2、现有校舍1000平方米,410名学生,其中寄宿生将近 -
当前视讯!协会资讯|汽车金融行业培训需求研讨会在天津成功举办协会资讯|汽车金融行业培训需求研讨会在天津成功举办 -
每日精选:亮剑[李幼斌版][720P高清][MKV].mkv 百度网盘1、种发给你了,请查收,如果木有问题。2、还望采纳。本文到此分享完毕,希望对大家有所帮助。 -
今日热文:沪滇携手 舞动春天——上海戏剧学院附属舞蹈学校赴红河哈尼梯田文化传承学校交流沪滇携手舞动春天——上海戏剧学院附属舞蹈学校赴红河哈尼梯田文化传承学校交流 -
【新要闻】属牛和虎能在一起吗 给属牛及属虎之人的建议婚姻里没有两个人是绝对合适的,即便是六合生肖上等婚配,在一起久了也会有各种矛盾。对于爱情和婚姻,我们要知道,没有一个人是为了量身定做 -
每日热议!龚自珍代表作(龚自珍代表作)1、[清]龚自珍浩荡离愁白日斜,吟鞭东指即天涯。2、落红不是无情物,化作春泥更护花。3、龚自珍的诗【注释】:清道光十年(1839)春末,龚自珍因 -
【快播报】贵州省公路开发集团有限公司怎么样?贵州省公路开发集团有限公司于2016年12月9日挂牌成立,注册资本20亿元;经营范围包括交通基础设施和交通运输产业的投资、建设及经营管理,交通 -
最资讯丨展现中华文明多元一体的演进格局!重庆“錞于王”亮相这所博物馆日前,由中国航海博物馆和重庆中国三峡博物馆联合举办的“寻巴记:中华文明多元一体系列展•贰”在上海中国航海博物馆开幕。此次展览是继20... -
全球球精选!蓬莱开发区8个项目年内完成主体施工蓬莱开发区8个项目年内完成主体施工 -
热点在线丨航天信息(600271):3月15日北向资金减持20.19万股3月15日北向资金减持20 19万股航天信息。近5个交易日中,获北向资金增持的有2天,累计净增持233 69万股。近20个交易日中,获北向资金增持的有2 -
【当前独家】云顶之弈龙魂阵容小炮出装_云顶之弈 龙魂小炮天选怎么玩1、用天选龙魂小炮棋子搭配上其他强力龙魂棋子,凑齐龙魂羁绊,然后再混搭上神射手棋子和重装战士棋子。2、天选龙魂小炮,可以 -
环球头条:天源环保股东户数增加1.17%,户均持股8.67万元天源环保最新股东户数2 93万户,高于行业平均水平。公司户均持有流通股份8356股;户均流通市值8 67万元。 -
快资讯丨爱旭股份实控人陈刚巧用“定增+关联交易”组合拳套利?包场定增大赚40亿核心观点:近年,爱旭股份关联交易急剧攀升,预付款也大幅上涨至近20亿元。公司实控人体外公司刚成立不久便与上市公司发生关联交易流出体外。 -
快看点丨父亲回应16岁女儿众筹登珠峰是什么情况父亲回应16岁女儿众筹登珠峰今天的热度非常高,现在也是在热搜榜上了,那么具体的父亲回应16岁女儿众筹登珠峰是什么情况呢,大家可以一起来看 -
【速看料】最后一次性生活后多久能测出怀孕_同房后多久可以验孕1、同房后多久可以验孕,与采用的验孕方法有关,需要具体分析。2、目前临床上主要有三种验孕方法:1。临床上更早更准确的检测 -
焦点热文:山西证券:给予海正生材增持评级山西证券:给予海正生材增持评级 -
世界微头条丨全国有多少万达广场_全国有多少个万达广场1、截至2009年底,本公司已经在全国21个省、自治区和直辖市的32个重点城市投资建设了37个万达广场,其中已开业13个 -
环球今日讯!第二轮裁员开启! Meta(META.US)计划裁员1万人 并推动“扁平化”浪潮Facebook母公司MetaPlatforms(META US)计划在第二轮裁员中总计裁员约10,000人,并关闭在过去六个月的约5,000个额外的尚未填补空缺职位。Meta一 -
全球实时:右肩胛骨下方疼痛是怎么回事_肩胛骨下方疼痛是怎么回事1、肩胛骨下方疼痛是肩周炎的常见表现的,肩周炎好发年龄在50岁左右的人身上,女性发病率略高于男性,多见于体力劳动的人。2 -
世界热头条丨山东虐吉林!沃特35+16,刘冠岑再爆,小外陈培东狂铁,王晗辣眼山东虐吉林!沃特35+16,刘冠岑再爆,小外陈培东狂铁,王晗辣眼,王晗,贾诚,沃特,刘冠岑,陈培东,陶汉林,高诗岩,吉林省,山东省,本土球员 -
全球看点:2023年天津桃花节什么时候开始?》》》2023年天津桃花节什么时候开始?开始时间:3月17日结束时间:3月26日持续时间:共计10天游玩提示:1 建议绿色出行:尽量选择公共交通出 -
环球聚焦:雅士利国际(01230.HK)3月14日收盘平盘,主力资金净流出128.82万港元截至2023年3月14日收盘,雅士利国际(01230 HK)报收于1 18港元,上涨0 0%,换手率0 03%,成交量126 4万股,成交额147 9万港元。 -
全球简讯:祭奠是什么意思_祭祀是什么意思1、黄历上的“宜”和“忌”指的就是适合做什么和不适合做什么。2、安香祭祀实际就是指的祭奠活动,比如祭拜先人等等。本文分享 -
当前速递!两盘大战过关!世界第一掀翻前美网冠军,强势晋级继续卫冕之旅第7局和第9局斯瓦泰克两次破发,5-4领先来到发球胜赛局。最终在一场耗时2小时07分钟的比赛当中,斯瓦泰克以6-3 7-6战胜了安德莱斯库,将双方之 -
快资讯丨甘化科工董秘回复:请参考公司同日就类似问题的甘化科工(000576)03月14日在投资者关系平台上答复了投资者关心的问题。 -
全球消息!金門二胆島士兵游泳去大陸,現在已經安抵廈門,並公開表示他願意留在廈門此事件在台軍內部已引起廣泛討論,在當前台海戰爭壓力越來越大的情況,極可能出現群起效尤的示範效果,甚至引發前線士氣崩盤的危 -
全球热点评!翻译整个文档_文档翻译1、首先设置翻译语言,点击审核-翻译-选择翻译语言。2、设置翻译语言和翻译屏幕提示;3、以【英文】翻译成【中文】且提示为
