springboot 开启一个异步线程 |
您所在的位置:网站首页 › springboot工具类 › springboot 开启一个异步线程 |
使用步骤: 在Application类上加上 @EnableAsync 注解开启异步在被调用的方法上面加上 @Async,也可以直接在类上加此注解,会标识所有方法为异步方法如下方式会使@Async失效 异步方法使用static修饰 异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类 异步方法不能与被调用的异步方法在同一个类中 类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象 如果使用SpringBoot框架在启动类或配置类中增加@EnableAsync注解 线程池参考链接: https://www.bbsmax.com/A/8Bz8QWwXJx/ 一 介绍工作中经常涉及异步任务,通常是使用多线程技术,比如线程池ThreadPoolExecutor,但使用Executors容易产生OOM,需要手动使用ThreadPoolExecutor创建线程池;在springboot使用 @async 可以实现异步调用,配置线程池参数,可以简单的实现多线程的线程池效果,从而简化开发,避免OOM; 二 异步调用 2.1无返回异步我们知道同步执行就是按照代码的顺序执行,而异步执行则是无序,在springboot中使用实现异步调用函数非常简单,首先在启动类上加上@EnableAsync 注解; /** * @Author lsc **/ @SpringBootApplication @EnableAsync public class AsyncRunApp { public static void main(String[] args) { SpringApplication.run(AsyncRunApp.class, args); } } 其次,在函数上标上@sync注解,表示异步调用 @Async public void taskOne() throws Exception { System.out.println("任务一"); } @Async public void taskTwo() throws Exception { System.out.println("任务二"); }测试代码 @Autowired Task task; @Test public void test() throws Exception { task.taskOne(); task.taskTwo(); }如果按照同步执行逻辑会先执行任务一,然后再执行任务二,如果是异步执行,则无序,可能任务一先执行,也可能任务二先执行; 有时候要知道任务是否执行完成,再继续做其它的业务逻辑,就需要使用到Future接口,其含义是在执行异步任务后会给一个回调函数,我们只要设置回调信息,就可以知道任务是否正确执行完成;我们对异步函数,添加 Future 返回值类型,使用 new AsyncResult() 设置回调信息; @Component public class Task { @Async public Future taskOne() throws Exception { System.out.println("任务一"); return new AsyncResult("任务一执行完成"); } @Async public Future taskTwo() throws Exception { System.out.println("任务二"); return new AsyncResult("任务二执行完成"); } }测试代码如下, 等待2个任务全部完成后就打印出返回值信息 @Autowired Task task; @Test public void test() throws Exception { Future str1 = task.taskOne(); Future str2 = task.taskTwo(); while (true){ // 如果任务都做完就执行如下逻辑 if (str1.isDone() && str2.isDone()){ System.out.println(str1.get()+":"+str2.get()); break; } } }执行输出 任务二 任务一 任务一执行完成:任务二执行完成三 线程池 在异步掉用中使用的@Async 注解,默认的线程池大小如下; # 核心线程数 spring.task.execution.pool.core-size=8 # 最大线程数 spring.task.execution.pool.max-size=16 # 空闲线程存活时间 spring.task.execution.pool.keep-alive=60s # 是否允许核心线程超时 spring.task.execution.pool.allow-core-thread-timeout=true # 线程队列数量 spring.task.execution.pool.queue-capacity=100 # 线程关闭等待 spring.task.execution.shutdown.await-termination=false spring.task.execution.shutdown.await-termination-period= # 线程名称前缀 spring.task.execution.thread-name-prefix=task-一般情况下,我们都需要手动创建线程池,使用 ThreadPoolTaskExecutor 类进行配置;这边设置了线程前缀名称,等下测试时就可以判定是否线程池配置成功; @Configuration public class PoolConfig { @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(10); // 设置最大线程数 executor.setMaxPoolSize(15); // 设置队列容量 executor.setQueueCapacity(20); // 设置线程活跃时间(秒) executor.setKeepAliveSeconds(60); // 设置默认线程名称 executor.setThreadNamePrefix("zszxz-"); // 设置拒绝策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 等待所有任务结束后再关闭线程池 executor.setWaitForTasksToCompleteOnShutdown(true); return executor; } }在task类中加上 新的一个方法如下 @Async public void sayHello(String name) { LoggerFactory.getLogger(Task.class).info(name + ":Hello World!"); }使用测试类进行测试 @Test public void testPool() throws Exception { task.sayHello("公众号:知识追寻者"); }执行结果如下,日志打印出线程名称为zszxz-1; 有时候,一个项目中如果配置了多个线程池,如下格式 @Bean("pool1") public TaskExecutor taskExecutor1() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //.... return executor; } @Bean("pool2") public TaskExecutor taskExecutor2() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //.... return executor; } @Bean("pool3") public TaskExecutor taskExecutor3() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //.... return executor; }在使用 @Async注解时就需要指明具体使用的线程池,如下格式 @Async("pool1") public void sayHello1(String name) { LoggerFactory.getLogger(Task.class).info(name + ":Hello World!"); } @Async("pool2") public void sayHello1(String name) { LoggerFactory.getLogger(Task.class).info(name + ":Hello World!"); }源码地址:https://github.com/zszxz/study-springboot
参考链接: https://blog.csdn.net/youku1327/article/details/111406143 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |