范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

SpringBoot中如何优雅的使用多线程

  在 SpringBoot 应用中,经常会遇到在一个接口中,同时做事情1,事情2,事情3,如果同步执行的话,则本次接口时间取决于事情1 2 3执行时间之和;如果三件事同时执行,则本次接口时间取决于事情1 2 3执行时间最长的那个,合理使用多线程,可以大大缩短接口时间。那么在 SpringBoot 应用中如何优雅的使用多线程呢?
  Don"t bb, show me code.快速使用
  SpringBoot应用中需要添加@EnableAsync注解,来开启异步调用,一般还会配置一个线程池,异步的方法交给特定的线程池完成,如下:@Configuration @EnableAsync public 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注解@RestController public 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);         }         return "success";     } }   @Slf4j @Service public 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 milliseconds 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-1] x.gits.boot.system.service.AsyncService  : do something, message=index = 0 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-5] x.gits.boot.system.service.AsyncService  : do something, message=index = 4 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-4] x.gits.boot.system.service.AsyncService  : do something, message=index = 3 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-6] x.gits.boot.system.service.AsyncService  : do something, message=index = 5 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-9] x.gits.boot.system.service.AsyncService  : do something, message=index = 8 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-8] x.gits.boot.system.service.AsyncService  : do something, message=index = 7 2020-04-19 23:42:42.488  INFO 21168 --- [do-something-10] x.gits.boot.system.service.AsyncService  : do something, message=index = 9 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-7] x.gits.boot.system.service.AsyncService  : do something, message=index = 6 2020-04-19 23:42:42.488  INFO 21168 --- [ do-something-2] x.gits.boot.system.service.AsyncService  : do something, message=index = 1 2020-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可以将多个异步任务进行复杂的组合。如下:@RestController public 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 @Service public 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:UsersAdministrator>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 log 2020-04-20 00:27:42.238  INFO 5672 --- [ do-something-2] x.gits.boot.system.service.AsyncService  : do something2: reduce account 2020-04-20 00:27:42.238  INFO 5672 --- [ do-something-1] x.gits.boot.system.service.AsyncService  : do something1: create order 复制代码注意事项
  @Async注解会在以下几个场景失效,也就是说明明使用了@Async注解,但就没有走多线程。异步方法使用static关键词修饰;异步类不是一个Spring容器的bean(一般使用注解@Component和@Service,并且能被Spring扫描到);SpringBoot应用中没有添加@EnableAsync注解;在同一个类中,一个方法调用另外一个有@Async注解的方法,注解不会生效。原因是@Async注解的方法,是在代理类中执行的。
  需要注意的是: 异步方法使用注解@Async的返回值只能为void或者Future及其子类,当返回结果为其他类型时,方法还是会异步执行,但是返回值都是null,部分源码如下:
  AsyncExecutionInterceptor#invoke
  通过上边几个示例,@Async实际还是通过Future或CompletableFuture来异步执行的,Spring又封装了一下,让我们使用的更方便。

华为P50Pro开放100元定金预售,每天1008发售目前华为P50Pro京东商城已经开放100元定金预售,每天1008限量发售,6488元起(8GB256GB)。据悉,此次华为P50Pro共有海思麒麟90004G芯片与高通骁龙888近视夜跑想听歌怎么办?试试可怡骨传导蓝牙眼镜根据马里兰医疗中心大学去年的一项研究,在过去6年里,行人戴着耳机出车祸的数字增长了3倍。更严重的是,70的事故中,跑步者或者行人不治身亡。夜跑对近视眼太不友好了!大量出汗带着又很不一年一度的运通汽车嘉年华,火热开启,您准备好了吗第七届运通嘉年华即将火热开启,7月24日30日,老时间,新玩法加倍福利等你拿!快带着小伙伴,一起体验精彩车生活。时至今日,运通集团已经成功举办6届运通嘉年华,往届多彩的活动丰厚的福3A平台加持ROG魔霸5R解锁极致性能战力要论专业电竞品牌,ROG必定榜上有名。凭借强大的实力积累,ROG软硬兼施不断推陈出新,为玩家们带来顶级笔记本产品,而ROG魔霸5R便是今年实力性能本的代表之一。作为笔记本市场罕见的5位达达快送骑能异士组团出道追逐平凡人滚烫火辣的梦想人生披荆斩棘的哥哥自播出后,各大平台话题不断,备受观众的喜爱与关注,成为当下最热门的网络综艺之一。而金典作为节目独家冠名品牌,联合达达集团旗下本地即时零售平台京东到家本地即时配送平台达一拳超人难想象的场景,埼玉爆破还有龙卷组队打BOSS,谁扛得住?看过一拳超人动漫的朋友应该知道,在这部动漫中,每个英雄都有相应的评级,而根据原著中的实力排行,这其中总共出现了17位S级英雄。而这17位S级英雄中,公认最强的三位分别是爆破龙卷以及小家也能实现大屏自由,峰米R1搭载联发科MT9669硬件实力出众随着现代家居环境和人们观影习惯的改变,投影产品正成为众多家庭的共同选择。尤其是随放随用无投影距离限制的激光超短焦投影仪,成为现代家庭实现大屏自由的不二之选。火热的市场催生了大量优质永劫无间风靡全球华硕重炮手主板助你吃鸡永劫无间将在8月12日登陆SteamEpic平台开启全球公测,届时除了阴阳师联名的妖刀姬参战外,全新英雄也会一一亮相,另外全新武器匕首也将随着第一赛季一同推出。该作于去年开放测试后MPV教科书混动天花板,广汽丰田赛那能不能买?从去年五月份首发至今,新一代丰田SIENNA(中文名赛那)的相关信息就一直是媒体和车友关注的重点。10月30日,广汽丰田赛那SIENNA正式上市,这是丰田TNGA架构下的首款MPV惊悚回归死亡空间重制版公布制作随着近几年网络视频直播行业的发展,一些惊悚动作类游戏的热度逐渐攀升甚至出圈已屡见不鲜,尤其是一些经典的恐怖动作类游戏,如寂静岭逃生生化危机等,每一次推出精神续作都能收获忠实粉丝的大广汽蔚来焕新而来,助力自动驾驶新生态落地广州广汽蔚来焕新而来,助力自动驾驶新生态落地广州2021年中国汽车行业电动化转型加速,新能源汽车销量快速放大,今年第一季度国内汽车市场新能源汽车的销量为46。6万台。新能源车市场正逐渐
惠普更新薄锐系列笔记本和x360变形本,添加语音助手和摄像头隐私开关记者彭新在稍早举行的惠普全球合作伙伴大会上,惠普宣布更新旗下薄锐(Envy)系列笔记本电脑和x360变形本设备,共计四款新产品,新款笔记本电脑搭载了最新的英特尔和AMD处理器,将在ATM机时代落幕,曾经代表先进科技的ATM机是被谁击败的?不知道大家有多久没有去ATM机里面取钱了,似乎每年除了过年要发红包的时候之外,实在想不起来ATM机还能有什么样的作用?ATM机作为世界金融业的最重要发明,曾经被成为改变银行划时代的手机彻夜充电,对电池有损伤吗?该如何充电?手机彻夜充电,对电池的损伤是微乎其微的,因为手机内部都设置有多重过充保护电路,锂电池在充满后即使插电也不会继续充电,而是待电池电压下降到一定程度再自动补充,这种充电方式对电池带来的继金立之后,又一个国产手机品牌将凉凉,终究还是熬不过智能手机品牌之战已经进入了下半场,曾经手机品牌的百团大战,现在只剩下为数不多的几家,而且残酷的竞争环境依旧还在上演。此前金立就宣告了它的终结,而且将手机品牌出售给了印度厂商。紧接着时隔两年,PuTTY发布了一个新的安全修复版本日前,得益于欧盟资助的HackerOne平台,PuTTY发布了0。71版本,主要是修复了大量的安全缺陷。这个版本距其上个版本0。70的发布已近两年。老王PuTTY是Windows上Java12的新特性Java语言特性系列Java5的新特性Java6的新特性Java7的新特性Java8的新特性Java9的新特性Java10的新特性Java11的新特性Java12的新特性Java1外国人发明楼道电梯,老年人上下楼太简单,没电梯的老房子有福了现在社会的发展速度很快,城市处处都是高楼林立,为了符合现代化进程的发展,房地产开发商特意将格局设计成了带有电梯的大楼。但是在早年所建的房子里根本还没有电梯这个说法,为了方便上下楼,拳打USB3。1,脚踢DisplayPort,这项在高端电脑配备的技术太强悍在一些高端的笔记本电脑上,像MacbookPro,SurfaceBook都会带有一个或几个带雷电标志的接口。仔细看,这个接口的外观和手机上的USBTypeC接口一模一样,但事实上这麦肯锡全球移动变革报告20年内中国交通面貌或将焕然一新中国欧洲巴西印度和美国的地区差异将如何重塑汽车汽车制造商和汽车用户体验?移动出行革命的第一个大拐点最初出现在1910年左右的美国,并从那里扩散开来。第二个拐点将遵循不同的路径在更多又一家国际大厂裁员千余人,两年后关门!提到爱普生,很多人的第一反应是打印机。爱普生是当今世界知名的打印机制造企业,而今天提到的日本精工爱普生公司是爱普生集团的核心企业之一。裁员风声四起此次传出爱普生将关闭的工厂,其实具中国冷链物流赚钱之道运点点导读冷链物流是近年来,物流行业内最火爆的项目。各大巨头都把目光盯向了冷链物流,有钱但不代表就能做好冷链物流。近年来,中国冷链物流市场发生了质的变化,原因是对食材的新鲜程度要求