zoukankan      html  css  js  c++  java
  • SpingBoot @Async的使用

    项目工程结构

    image

    定义一个业务类,有4个业务

    package com.demo.testasync.service;
    
    import java.util.concurrent.Future;
    
    public interface TestService {
    
        /**
         * 异步调用,无返回值
         */
        void asyncTask1();
    
        /**
         * 异步调用,无返回值
         */
        void asyncTask2();
    
        /**
         * 异步调用,有返回值
         *
         * @param s 年代
         * @return {@link Future}
         * Future表示一个可能还没有完成的异步任务的结果
         */
        Future asyncTask1(String s);
    
        /**
         * 异步调用,有返回值
         *
         * @param s 年代
         * @return {@link Future}
         * Future表示一个可能还没有完成的异步任务的结果
         */
        Future asyncTask2(String s);
    
    
    
    }
    
    

    业务实现类

    
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.AsyncResult;
    import org.springframework.stereotype.Service;
    
    import java.util.concurrent.Future;
    
    @Service
    public class TestServiceImpl implements TestService {
    
    
    
        @Async("doAsyncTaskExecutor")
        @Override
        public void asyncTask1() {
            long startTime = System.currentTimeMillis();
    
            // 模拟耗时
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            long endTime = System.currentTimeMillis();
    
            System.out.println(Thread.currentThread() + ",asyncTask(),耗时:" + (endTime - startTime));
    
        }
    
        @Async("doAsyncTaskExecutor")
        @Override
        public void asyncTask2() {
            long startTime = System.currentTimeMillis();
    
            // 模拟耗时
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            long endTime = System.currentTimeMillis();
    
            System.out.println(Thread.currentThread() + ",asyncTask(),耗时:" + (endTime - startTime));
    
        }
    
        @Async("doAsyncTaskExecutor")
        @Override
        public Future asyncTask1(String s) {
            long startTime = System.currentTimeMillis();
    
            // 模拟耗时
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            long endTime = System.currentTimeMillis();
    
            System.out.println(Thread.currentThread() + ",asyncTask(String s),耗时:" + (endTime - startTime));
    
            return AsyncResult.forValue(s);
        }
    
        @Async("doAsyncTaskExecutor")
        @Override
        public Future asyncTask2(String s) {
            long startTime = System.currentTimeMillis();
    
            // 模拟耗时
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            long endTime = System.currentTimeMillis();
    
            System.out.println(Thread.currentThread() + ",asyncTask(String s),耗时:" + (endTime - startTime));
    
            return AsyncResult.forValue(s);
        }
    }
    

    线程池配置

    配置完成后@Async会默认从线程池获取线程,当然也可以显式的指定@Async("doAsyncTaskExecutor")

    package com.demo.testasync.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.task.AsyncTaskExecutor;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    
    import java.util.concurrent.ThreadPoolExecutor;
    
    @Configuration
    public class AsyncConfig {
    
        private static final int MAX_POOL_SIZE = 500;
    
        private static final int CORE_POOL_SIZE = 20;
    
        @Bean("doAsyncTaskExecutor")
        AsyncTaskExecutor doAsyncTaskExecutor(){
            ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
            //配置核心线程数
            threadPoolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
            //配置最大线程数
            threadPoolTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
            //配置队列大小
            threadPoolTaskExecutor.setQueueCapacity(200);
            //线程池维护线程所允许的空闲时间
            threadPoolTaskExecutor.setKeepAliveSeconds(30);
            //配置线程池中的线程的名称前缀
            threadPoolTaskExecutor.setThreadNamePrefix("yoyo");
            //设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
            threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            //设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
            threadPoolTaskExecutor.setAwaitTerminationSeconds(60);
            // rejection-policy:当pool已经达到max size的时候,如何处理新任务
            // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
            threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            //执行初始化
            threadPoolTaskExecutor.initialize();
    
    
            return threadPoolTaskExecutor;
        }
    
    }
    
    

    在ApplicationRunner中初始化业务方法的实现,这样启动项目后,业务方法会自动异步执行

    package com.demo.testasync.job;
    
    import com.demo.testasync.service.TestService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    
    @Component
    public class RunThread {
    
        @Autowired
        TestService testService;
    
        @Bean
        public ApplicationRunner applicationRunner() {
            return applicationArguments -> {
                long startTime = System.currentTimeMillis();
                System.out.println(Thread.currentThread().getName() + ":开始调用异步业务");
    
                //无返回值
                testService.asyncTask1();
                testService.asyncTask2();
                testService.asyncTask1("haha1");
                testService.asyncTask2("haha2");
    
                long endTime = System.currentTimeMillis();
                System.out.println(Thread.currentThread().getName() + ":调用异步业务结束,耗时:" + (endTime - startTime));
            };
        }
    
    
    }
    
    

    在启动类上加上@EnableAsync注解

    package com.demo.testasync;
    
    import com.demo.testasync.service.TestService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.stereotype.Component;
    
    @SpringBootApplication
    @EnableAsync
    public class TestasyncApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(TestasyncApplication.class, args);
        }
    
    }
    

    效果

    image

  • 相关阅读:
    #18.2.27 codevs1098 均分纸牌
    18.2.26 codevs3143 二叉树的序遍历
    18.2.14 codevs1501 二叉树最大宽度和高度
    18.2.14 codevs1011 数的计算
    18.2.14 【水】codevs1475 m进制转十进制
    18.2.14 【水】codevs1474 十进制转m进制
    18.2.14 【水】codevs1430 素数判定
    18.2.13 codevs1212 最大公约数
    18.2.13 codevs1012 最大公约数和最小公倍数问题
    17.12.31 链表合并
  • 原文地址:https://www.cnblogs.com/lyd447113735/p/15324210.html
Copyright © 2011-2022 走看看