[线程池]Springboot如何使用线程池-播资讯
发布时间:2023-03-18 07:23:03 文章来源:腾讯云

本文带你快速了解@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注解,但就没有走多线程。

异步方法使用static关键词修饰;异步类不是一个Spring容器的bean(一般使用注解@Component@Service,并且能被Spring扫描到);SpringBoot应用中没有添加@EnableAsync注解;在同一个类中,一个方法调用另外一个有@Async注解的方法,注解不会生效。原因是@Async注解的方法,是在代理类中执行的。

通过上边几个示例,@Async实际还是通过Future或CompletableFuture来异步执行的,Spring又封装了一下,让我们使用的更方便。

关键词:

热门推荐HOT

  • [线程池]Springboot如何使用线程池-播资讯
    [线程池]Springboot如何使用线程

    在SpringBoot应用中,经常会遇到在一个接口中,同时做事情1,事情2,事情3,如果同步执行的话,则本次接口时间取决于事情123执行时间之和;如果三

  • 爱旭股份业绩狂飙 机构认为还有97.45%的向上空间
    爱旭股份业绩狂飙 机构认为还有

    本周,A股市场整体呈沪强深弱的态势。这样的市况中,机构研究员的动向又是怎么样的呢?据投资快报投研通数据统计,本周券商研究员对113家公司的

  • 新诺威去年净利润同比增84.70% 咖啡因量价齐升助推业绩增长
    新诺威去年净利润同比增84.70%

    3月17日,新诺威披露2022年度业绩报告。数据显示,新诺威去年实现营业收入26 26亿元,同比增长42%,实现归属于上市公司股东的净利润7 26亿元,

  • 乘号在键盘上怎么表示_乘号怎么用键盘打出来 全球关注
    乘号在键盘上怎么表示_乘号怎么

    1、有两种方法:当输入乘号的时候,把输入中文模式改为英文模式。2、然后点击一下X键到光标处,再将英文模式改为中文模式。3

  • 怎么收缩毛孔和去黑头_怎么收缩毛孔 焦点精选
    怎么收缩毛孔和去黑头_怎么收缩

    1、收缩毛孔的方法一:小苏打每次清洁脸部时,把小苏打混合洗面奶充分打起泡泡,这个时候你会发现泡泡变得非常细腻,涂抹在脸

  • 当前动态:孙立杰一行到软控欧洲研发中心考察调研
    当前动态:孙立杰一行到软控欧洲

    3月14日,中国驻斯洛伐克大使孙立杰、商务参赞王宏亮一行到软控欧洲研发中心考察调研。  软控股份董事长兼总裁官炳政等公司领导热情迎接来访

  • 博士眼镜:3月13日接受机构调研,安联基金、嘉实基金等多家机构参与
    博士眼镜:3月13日接受机构调研

    2023年3月17日博士眼镜(300622)发布公告称公司于2023年3月13日接受机构调研,安联基金、嘉实基金、民加基金、太平基金、泰达宏利、泰康资产

  • 一场及时雨!2023年首次全面降准,带来哪些利好? 天天快资讯
    一场及时雨!2023年首次全面降准

    中国商务新闻网是商务部国际商报社主办,国家互联网信息办公室批准的国家一类新闻网站,是全国商务系统网络宣传和信息服务的重要窗口,是我国

  • 山西证券:给予顺鑫农业增持评级 天天关注
    山西证券:给予顺鑫农业增持评级

    山西证券股份有限公司陈振志,周蓉近期对顺鑫农业进行研究并发布了研究报告《坚定聚焦白酒猪肉业务,产品结构升级打开新篇章》,本报告对顺鑫农

  • 每日信息:热力学第零定律是谁提出的_热力学第零定律
    每日信息:热力学第零定律是谁提

    1、热力学第零定律于1930年由福勒(R H Fowler)正式提出,比热力学第一定律和热力学第二定律晚了80余年。2、

最近更新

  • 【世界新要闻】科学家在中国发现脖子最长恐龙
    【世界新要闻】科学家在中国发现

    近日,一组中外科学家研究团队通过计算机断层扫描分析表明,在中国发现的一个马门溪龙标本的颈部长度达15米,比长颈鹿的脖子长6倍。据科学家称

  • 总投资225.7亿元 桐乡经开区项目建设热火朝天 当前聚焦
    总投资225.7亿元 桐乡经开区项

    中国商务新闻网是商务部国际商报社主办,国家互联网信息办公室批准的国家一类新闻网站,是全国商务系统网络宣传和信息服务的重要窗口,是我国

  • 重庆九龙坡一刻钟便民生活洋溢时尚活力 全球速看料
    重庆九龙坡一刻钟便民生活洋溢时

    中国商务新闻网是商务部国际商报社主办,国家互联网信息办公室批准的国家一类新闻网站,是全国商务系统网络宣传和信息服务的重要窗口,是我国

  • 每日热讯!为实现2030年电动汽车、氢能汽车达到450万辆目标 韩国应尽快出台生产鼓励政策
    每日热讯!为实现2030年电动汽车

    中国商务新闻网是商务部国际商报社主办,国家互联网信息办公室批准的国家一类新闻网站,是全国商务系统网络宣传和信息服务的重要窗口,是我国

  • 国家推出稳定今年大豆生产一揽子支持政策
    国家推出稳定今年大豆生产一揽子

    中国商务新闻网是商务部国际商报社主办,国家互联网信息办公室批准的国家一类新闻网站,是全国商务系统网络宣传和信息服务的重要窗口,是我国

  • 每日快报!《缅甸商标版权法》自2023年4月1日起生效
    每日快报!《缅甸商标版权法》自2

    中国商务新闻网是商务部国际商报社主办,国家互联网信息办公室批准的国家一类新闻网站,是全国商务系统网络宣传和信息服务的重要窗口,是我国

  • 3月17日山东地区加氢苯市场价格下调
    3月17日山东地区加氢苯市场价格

    山东地区加氢苯市场主流报价区间在6950~7000元 吨,均价6975元 吨,较上一交易日下调50元 吨。纯苯价格:京博石化报价7200元 吨,汇丰石化报价72

  • 看热讯:3月17日国内苯酐产业链部分价格上涨
    看热讯:3月17日国内苯酐产业链

    产品3月16日3月17日涨跌幅单位:元 吨OX850085000元 吨苯酐870087000元 吨DOP10000101000 1%元 吨3月17日苯酐市场价格

  • 世界观天下!3月17日利华益集团硫磺报价平稳
    世界观天下!3月17日利华益集团

    3月17日,利华益利津炼化有限公司工业硫磺报价1240元 吨,液体硫磺报价1240元 吨,3月14日企业调价,价格下调30元 吨,目前硫磺市场观望为主,

  • 全球今头条!3月17日万华化学苯乙烯价格动态
    全球今头条!3月17日万华化学苯

    3月17日,山东万华化学苯乙烯65万吨 年新装置正常产销,目前销售华北地区8600元 吨,华东地区8600元 吨,国际油价反弹,成本支撑较好,但苯乙

  • 成都银行联合社会多方力量 共建金融宣教基地 环球资讯
    成都银行联合社会多方力量 共建

    为进一步增强金融消费者自我权益保护意识,成都银行以“共筑诚信消费环境、提振金融消费信心”为主题,聚焦“一老一少一新”等重点群体,在立

  • 全球热头条丨数智引领、睿创新机 柏睿数据2023新品发布会在京举行
    全球热头条丨数智引领、睿创新机

    3月16日,柏睿数据在北京举办“数智引领睿创新机——柏睿数据2023新品发布媒体见面会”,全面升级未来数据智能战略,发布全新数据智能产品矩阵

  • 南京市秦淮区人社局领导一行莅临

    3月10日,南京市秦淮区人社局领导一行莅临云生集团走访交流。秦淮区人力资源和社会保障局副局长苏瑞中、人力资源管理科科长雷廷、秦淮区新管

  • 天天即时:3月17日华鲁恒升异辛醇价格上涨
    天天即时:3月17日华鲁恒升异辛

    3月17日,山东华鲁恒升集团异辛醇装置运行正常。出厂价格9500元 吨,报价上涨,涨幅100元 吨,实际成交价以协商为主。上游丙烯行情小幅上涨,

  • 环球滚动:3月17日国内部分乙醇厂家报价下调
    环球滚动:3月17日国内部分乙醇厂

    江苏东成生物科技15万吨 年木薯普级乙醇装置停机,企业普级对外报价下调50元 吨报6750元 吨。河南汉永酒精有限公司30万吨 年乙醇装置正常,优

猜你喜欢LOVE

Copyright @ 2001-2023 www.u74.cn All Rights Reserved 商业时报网 版权所有

网站信息内容, 均为相关单位具有著作权,未经书面授权,转载注明出处
未经商业时报网书面授权,请勿建立镜像,转载请注明来源,违者依法必究

皖ICP备2022009963号-4
联系邮箱:39 60 29 14 2@qq.com

关于我们 | 联系方式 | 供稿服务 | 版权声明 | 友情链接 | 合作伙伴 |