首页 > 社会万象

原来你是这样的SpringBoot--Async异步任务

来源:博客园 时间:2023-08-27 16:06:37

本节我们一起学习一下SpringBoot中的异步调用,主要用于优化耗时较长的操作,提高系统性能和吞吐量。

一、新建项目,启动异步调用

首先给启动类增加注解@EnableAsync,支持异步调用


(资料图)

@EnableAsync@SpringBootApplicationpublic class CathySpringbootDemoApplication {    public static void main(String[] args) {        SpringApplication.run(CathySpringbootDemoApplication.class, args);    }}

然后定义要执行的Task,分类增加一个同步方法和异步方法,其中异步方法需要增加注解@Async

@Componentpublic class AsyncTask {    /**     * 异步任务,需要注解@Async     *     * @param taskId 任务编号id     * @param second 执行时长,模拟慢任务     * @return     */    @Async    public Future asyncExec(int taskId, Long second) {        exec(taskId, second);        return new AsyncResult<>(Boolean.TRUE);    }    public void exec(int taskId, Long second) {        System.out.println("开始执行任务" + taskId);        try {            Thread.sleep(second * 1000);        } catch (InterruptedException e) {            throw new RuntimeException(e);        }        System.out.println("结束执行任务" + taskId);    }}

其实接下来就可以在controller中创建接口来进行简单的测试了

@RestController@RequestMapping("/async")public class AsyncController {    @Autowired    AsyncTask asyncTask;    @GetMapping("sync_task")    public String syncTask() {        long start = System.currentTimeMillis();        asyncTask.exec(1, 3L);        asyncTask.exec(2, 3L);        asyncTask.exec(3, 3L);        long time = System.currentTimeMillis() - start;        return "同步执行,耗时" + time;    }    @GetMapping("async_task")    public String asyncTask() {        long start = System.currentTimeMillis();        Future f1 = asyncTask.asyncExec(1, 3L);        Future f2 = asyncTask.asyncExec(2, 3L);        Future f3 = asyncTask.asyncExec(3, 3L);        try {            f1.get();            f2.get();            f3.get();        } catch (InterruptedException e) {            throw new RuntimeException(e);        } catch (ExecutionException e) {            throw new RuntimeException(e);        }        long time = System.currentTimeMillis() - start;        return "异步执行,耗时" + time;    }}

启动程序,查看接口响应结果:http://localhost:16001/async/sync_task

http://localhost:16001/async/async_task

注意:异步方法和调用一定要写在不同的类中

二、线程池配置

上面的例子,在耗时服务多的情况下,使用异步方法确实提高了响应速度。但是它默认启用的是Spring默认的线程池SimpleAsyncTaskExecutor,不太灵活。我们把异步请求多增加几次调用看看效果:

@GetMapping("async_task")    public String asyncTask() {        long start = System.currentTimeMillis();        List> list = new ArrayList<>();        for (int i = 0; i < 20; i++) {            Future fi = asyncTask.asyncExec(i, 10L);            list.add(fi);        }        for (int i = 0; i < 20; i++) {            list.forEach(x -> {                try {                    x.get();                } catch (InterruptedException e) {                    throw new RuntimeException(e);                } catch (ExecutionException e) {                    throw new RuntimeException(e);                }            });        }        long time = System.currentTimeMillis() - start;        return "异步执行,耗时" + time;    }

从上面的运行效果来看,一旦超过8个并行执行的任务,就开始出现等待了。

接下来,我们自定义线程池

@Bean public TaskExecutor threadPoolTaskExecutor(){     ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();     executor.setCorePoolSize(8);     executor.setMaxPoolSize(16);     executor.setQueueCapacity(20);     executor.setKeepAliveSeconds(30);     executor.setWaitForTasksToCompleteOnShutdown(true);     executor.setThreadNamePrefix("task-thread-");     executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());     executor.initialize();     return executor; }

然后在异步方法的注解中,明确指定所使用的线程池

@Async("threadPoolTaskExecutor")    public Future asyncExec(int taskId, Long second) {        exec(taskId, second);        return new AsyncResult<>(Boolean.TRUE);    }

执行效果如下:

可以看出,线程池设置的参数已经生效。

本人公众号[ 敬YES]同步更新,欢迎大家关注~

相关稿件

原来你是这样的SpringBoot--Async异步任务

含有渗字的成语

科技部:2项重点专项项目视频答辩会将召开

AI专家:大模型同质化严重 面临十大科学挑战

草莓南果优质高效生产高素质农民培训班在京举办

大学生学业规划服务,你会购买吗?

车展速递丨睿蓝7开启预售 价格下探至15万元内

《闪电十一人》15周年纪念影片公开!系列新作年内发售

米码头: 老塑料厂房里玩起“潮文化”

银河战舰冲击波?吧友们如何评价HLE今年的表现

女冰世锦赛中国队2-1战胜荷兰队 五连胜结束征程

游戏网名大全2023最新版(游戏网名)

宁波市工业投资有限责任公司(关于宁波市工业投资有限责任公司简述)

萧岩寿(关于萧岩寿简述)

通知范文版(正规通知格式范文)

金士顿 骇客神条 fury 系列 ddr3 1600 8gb(金士顿骇客神条和普通的区别)

数据显示:榴莲消费热度高

土拍速递!济宁市一宗土地成功出让!

建设示范基地 打造区域品牌!元江发挥热区资源优势发展特色高效农业

元宵的做法(元宵跟汤圆)

原油开采行业大型双轴双槽集热系统在内蒙古建成

多彩贵州文化艺术节|找到了,它就是可以穿越时空的天籁之音!

多彩张掖:擦亮丝路古城新名片

还未发布就获得广泛关注,OPPO Watch 4 Pro相比上一代有哪些提升?

谢治宇卸任200亿明星基兴全趋势,董理单飞

创世西游关服 创世西游2官网

请问低调做人 高调做事 是什么意思啊 请问低调做人 高调做事 是什么意思

快慢之间读懂大鹏

菲利普·特瓦济克(关于菲利普·特瓦济克简述)

被嫌弃大半年的iPhone 14,加上15也快来了,今天还值得入手吗?