栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot-27- @Async实现异步调用 什么是异步调用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot-27- @Async实现异步调用
什么是异步调用

SpringBoot-27- @Async实现异步调用 什么是异步调用

异步调用是相对于同步调用的,同步调用是按照顺序进行执行任务,只有上一个任务执行完成下一个任务才能执行,异步调用是指在按照顺序执行任务的过程中不需要等待任务结果的出现,就可以顺序执行下一个任务。

异步处理的方式:

Java异步处理:Thread/Runnable、Callable/Future

Servlet 3.0异步处理: asyncSupported、AsyncContext

Spring MVC异步处理: @Async、AsyncTaskExecutor

SpringBoot自身没有对异步调用做很大的变动,基本还是使用SpringMVC的@Async

开启异步调用配置
@EnableAsync
@Configuration
public class MyEnableAsyncConfig {
}

注解:在使用**@EnableWebMvc**注解的时候也可以开启异步调用,但是在SpringBoot中使用异步调用会使得SpringBoot的AutoConfig一部分功能失效。

定义线程池

定义一个或者多个线程池

@EnableAsync
@Configuration
public class MyEnableAsyncConfig {
    @Bean(name = "threadPoolTaskExecutor1")
    public Executor taskExecutor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("threadPoolTaskExecutor1-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    @Bean(name = "threadPoolTaskExecutor2")
    public Executor threadPoolTaskExecutor2() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("threadPoolTaskExecutor2-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}


我们使用ThreadPoolTaskExecutor创建线程池,其参数配置如下:

CorePoolSize:设置核心线程数,线程池创建的时候创建线程的个数

MaxPoolSize:最大线程数,在换成队列满以后才会申请超过核心线程的线程

QueueCapacity:缓冲队列,用来缓冲执行任务的队列

KeepAliveSeconds:当超过了核心线程数之外的线程在空闲时间到达之后会被销毁

ThreadNamePrefix:线程名称前缀

定义异步调用方法

异步调用方法有两种一个是没有返回值的,一种是有返回值的,具体实现如下:

@Component
public class ComponentTask {

    public static Random random =new Random();

    
    @Async("threadPoolTaskExecutor2")
    public void asyncMethodWithVoidReturnType_One() throws InterruptedException {
        System.out.println("开始做asyncMethodWithVoidReturnType_One");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(1000));
        long end = System.currentTimeMillis();
        System.out.println("完成asyncMethodWithVoidReturnType_One,耗时:" + (end - start) + "毫秒"+"  threadname:"+Thread.currentThread().getName());


    }
    @Async("threadPoolTaskExecutor1")
    public void asyncMethodWithVoidReturnType_Two() throws InterruptedException {
        System.out.println("开始做asyncMethodWithVoidReturnType_Two");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(2000));
        long end = System.currentTimeMillis();
        System.out.println("完成asyncMethodWithVoidReturnType_Two,耗时:" + (end - start) + "毫秒" +"  threadname:"+Thread.currentThread().getName());

    }
    @Async("threadPoolTaskExecutor1")
    public void asyncMethodWithVoidReturnType_Three() throws InterruptedException {
        System.out.println("开始做asyncMethodWithVoidReturnType_Three");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(3000));
        long end = System.currentTimeMillis();
        System.out.println("完成asyncMethodWithVoidReturnType_Three,耗时:" + (end - start) + "毫秒"+ "  threadname:"+Thread.currentThread().getName());

    }


    
    @Async("threadPoolTaskExecutor1")
    public Future asyncMethodWithReturnType_One() throws InterruptedException {
        System.out.println("开始asyncMethodWithReturnType_One");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("完成asyncMethodWithReturnType_One,耗时:" + (end - start) + "毫秒");
        return new AsyncResult<>("任务一完成");
    }
}


在多线程池的时候,我们需要在@Async()指定线程池名称**@Async(“threadPoolTaskExecutor1”)**

单元测试
@SpringBootTest
class SpringBootPart27ApplicationTests {
    @Autowired
    private ComponentTask componentTask;

    @Test
    void contextLoads() throws InterruptedException {
        componentTask.asyncMethodWithVoidReturnType_One();
        componentTask.asyncMethodWithVoidReturnType_Two();
        componentTask.asyncMethodWithVoidReturnType_Three();

        Thread.currentThread().join();

    }

}


在单元测试用例中,注入Task对象,并在测试用例中执行asyncMethodWithVoidReturnType_One、asyncMethodWithVoidReturnType_Two()、asyncMethodWithVoidReturnType_Three()三个函数。

执行结果如下:

开始做asyncMethodWithVoidReturnType_One
开始做asyncMethodWithVoidReturnType_Two
开始做asyncMethodWithVoidReturnType_Three
完成asyncMethodWithVoidReturnType_One,耗时:435毫秒  threadname:threadPoolTaskExecutor2-1
完成asyncMethodWithVoidReturnType_Two,耗时:1885毫秒  threadname:threadPoolTaskExecutor1-1
完成asyncMethodWithVoidReturnType_Three,耗时:1904毫秒  threadname:threadPoolTaskExecutor1-2

**

如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力!

**

原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/763159.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号