当前位置: 首页 > news >正文

SpringBoot 对Future模式的支持

  我们在实际项目中有些复杂运算、耗时操作,就可以利用多线程来充分利用CPU,提高系统吞吐量。SpringBoot对多线程支持非常好,对我们的开发非常便捷。
  Future模式是多线程开发中非常常见的一种设计模式。核心思想是异步调用。当我们执行一个方法时,方法中有多个耗时任务需要同时去做,而且又不着急等待这个结果时可以让客户端立即返回然后,后台慢慢去计算任务。
  当我们做一件事的时候需要等待,那么我们就可以在这个等待时间内来去做其它事情,这样就可以充分利用时间。比如我们点外卖,需要一段时间,那么我们在等外卖的时间里可以看点书,看个电影。这就是典型的Future模式。如果是普通模式的话,就是等外卖的时候就等外卖,外卖到了后再去看书,极大的浪费时间。
  SpringBoot对Future模式支持非常好,只需要简单的代码就能实现。

1.Future的相关方法

  • boolean cancel(boolean mayInterruptIfRunning); //可以在任务执行过程中取消任务
  • boolean isCancelled(); //判断Future任务是否取消
  • boolean isDone(); //判断任务是否完成
  • V get();//获取任务最终结果,这是一个阻塞方法,会等待任务执行好才会执行后面的代码
  • V get(long timeout, TimeUnit unit); //有等待时常的get方法,等待时间到了后仍然没有计算完成,则抛异常

2.需要的注解

 springboot 配置多线程需要两个注解

  1. @EnableAsync
    在配置类中通过加@EnableAsync开启对异步任务的支持
  2. @Async
    在需要执行的方法上加@Async表明该方法是个异步方法,如果加在类级别上,则表明类所有的方法都是异步方法

3.配置代码

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //核心线程数
        taskExecutor.setCorePoolSize(8);
        //最大线程数
        taskExecutor.setMaxPoolSize(16);
        //队列大小
        taskExecutor.setQueueCapacity(100);
        taskExecutor.initialize();
        return taskExecutor;
    }
}
复制代码

4.FutureService

@Service
public class FutureService {

    @Async
    public Future<String> futureTest() throws InterruptedException {
        System.out.println("任务执行开始,需要:1000ms");
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println("do:" + i);
        }
        System.out.println("完成任务");
        return new AsyncResult<>(Thread.currentThread().getName());
    }
}
复制代码

【注】这里的方法自动被注入使用上文配置的ThreadPoolTaskExecutor

5.测试代码

@Resource
private FutureService futureService;

@Test
public void futureTest() throws InterruptedException, ExecutionException {
    long start = System.currentTimeMillis();
    System.out.println("开始");
    //耗时任务
    Future<String> future = futureService.futureTest();
    //另外一个耗时任务
    Thread.sleep(500);
    System.out.println("另外一个耗时任务,需要500ms");

    String s = future.get();
    System.out.println("计算结果输出:" + s);
    System.out.println("共耗时:" + (System.currentTimeMillis() - start));
}
复制代码

6.运行结果

开始
2019-01-07 23:50:34.726  INFO 14648 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService
任务执行开始,需要:1000ms
do:0
do:1
do:2
do:3
另外一个耗时任务,需要500ms
do:4
do:5
do:6
do:7
do:8
do:9
完成任务
计算结果输出:ThreadPoolTaskExecutor-1
共耗时:1016

Process finished with exit code 0

复制代码

本来需要至少1500ms 执行的任务现在只需要1016ms, 因为在执行耗时任务1的同时也在执行耗时任务2,两个任务并行执行,这就是future模式的好处,在等待时间内去执行其它任务,能够充分利用时间

【注】本文基于SpringBoot 2.0

GitHub 连接


相关文章:

  • 20.4. tex2page
  • 在python中使用zookeeper管理你的应用集群
  • Docker启动/停止/进入容器的常见操作
  • 小论面向对象编程方法
  • git 下载代码到本地
  • Nginx安装、默认虚拟主机、用户认证、域名重定向
  • 七周七数据库
  • Android FM模块学习之四源码分析(八)
  • 初识MongoDB分片
  • BZOJ 2821 作诗(Poetize)(分块)
  • python学习笔记(九):操作数据库
  • Java今年最流行的三大框架你应该学习了
  • JSON数组,JSON对象,数组的区别与基本操作整理
  • 阿里云全球19个地域节点,哪个节点的服务器好,速度快?
  • 回顾2017:基础设施支出增长 思科占主导地位
  • 0x05 Python数据分析,Anaconda八斩刀
  • Android框架之Volley
  • canvas 高仿 Apple Watch 表盘
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • es6(二):字符串的扩展
  • HTTP 简介
  • JavaScript-Array类型
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • miaov-React 最佳入门
  • QQ浏览器x5内核的兼容性问题
  • WePY 在小程序性能调优上做出的探究
  • 关于Flux,Vuex,Redux的思考
  • 后端_MYSQL
  • 检测对象或数组
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 消息队列系列二(IOT中消息队列的应用)
  • 原生 js 实现移动端 Touch 滑动反弹
  • - 转 Ext2.0 form使用实例
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • Semaphore
  • #pragma multi_compile #pragma shader_feature
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (arch)linux 转换文件编码格式
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (待修改)PyG安装步骤
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (万字长文)Spring的核心知识尽揽其中
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .NET Core 中插件式开发实现
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...