SpringBoot学习–异步接口的配置和调用
总体概述
- 搭建基础SpringBoot环境。
- 添加异步配置类AsyncConfig.java。
- 添加测试Controller。
- 添加测试Service。
- 使用@Async将方法注解为异步方法。
搭建SpringBoot环境
建立maven项目。向pom.xml文件引入相关依赖
<!--spring-boot 依赖的父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
配置类AsyncConfig.java
- @Configuration注解为配置类
- @EnableAsync开启异步
- 继承AsyncConfigurer类
- 设置线程相关参数
package com.pzr.demo.config;
import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* 异步配置类
*
* @author ASUS
*
*/
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
// 线程池
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);//线程池核心线程数,控制每次开启子线程数量
taskExecutor.setMaxPoolSize(10);//线程池维护线程的最大数量
taskExecutor.setQueueCapacity(25);//线程池所使用的缓冲队列
taskExecutor.setKeepAliveSeconds(30000);//线程池维护线程所允许的空闲时间
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
控制层类AsyncController.java
包含两个例子(1:所有方法异步:。2:先异步,后集体等待,最后执行下异步操作。)
package com.pzr.demo.controller;
import java.util.Date;
import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.pzr.demo.service.AsyncService;
/**
* 异步请求 控制层
* @author ASUS
*
*/
@Controller
@RequestMapping("asyncController")
public class AsyncController {
@Autowired
AsyncService asyncService;
/**
* 异步
* @return
*/
@RequestMapping("asyncTest")
@ResponseBody
public String asyncTest(){
Date start = new Date();
asyncService.task1();
asyncService.task2();
asyncService.task3();
String resultStr = "主函数耗时:"+((new Date()).getTime() - start.getTime());
System.out.println(resultStr);
return resultStr;
}
/**
* 先异步,后集体等待再执行下一步
* @return
*/
@RequestMapping("cyclicBarrierTest")
@ResponseBody
public String cyclicBarrierTest(){
Date start = new Date();
Future<String> task1 = asyncService.task1();
Future<String> task2 = asyncService.task2();
Future<String> task3 = asyncService.task3();
while(true){
if(task1.isDone() && task2.isDone() && task3.isDone()){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String resultStr = "主函数耗时:"+((new Date()).getTime() - start.getTime());
System.out.println(resultStr);
return resultStr;
}
}
业务层接口AsyncService.java
package com.pzr.demo.service;
import java.util.concurrent.Future;
/**
* 异步请求 业务层
* @author ASUS
*
*/
public interface AsyncService {
public Future<String> task1();
public Future<String> task2();
public Future<String> task3();
}
业务层实现类AsyncServiceImpl.java
package com.pzr.demo.service.impl;
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import com.pzr.demo.service.AsyncService;
@Service
public class AsyncServiceImpl implements AsyncService {
@Override
@Async
public Future<String> task1() {
Future<String> result =null;
try {
Thread.sleep(10000);
System.out.println("任务1:耗时10秒"+Thread.currentThread().getName());
result =new AsyncResult<String>("任务1执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
@Override
@Async
public Future<String> task2() {
Future<String> result =null;
try {
Thread.sleep(5000);
System.out.println("任务2:耗时5秒"+Thread.currentThread().getName());
result =new AsyncResult<String>("任务2执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
@Override
@Async
public Future<String> task3() {
Future<String> result =null;
try {
Thread.sleep(15000);
System.out.println("任务3:耗时15秒"+Thread.currentThread().getName());
result =new AsyncResult<String>("任务3执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
}
结果
全部异步
可以看出主线程不会受到子线程的影响,第一个完成并返回数据,子线程根据睡眠时间长短依次打印。
主函数耗时:4
任务2:耗时5秒ThreadPoolTaskExecutor-2
任务1:耗时10秒ThreadPoolTaskExecutor-1
任务3:耗时15秒ThreadPoolTaskExecutor-3
先异步,后集体等待执行下一步
可以看出任务1,2,3是异步执行的,主线程等待子线程完成后再进行打印,总耗时接近于耗时最长的子线程时间。
任务2:耗时5秒ThreadPoolTaskExecutor-5
任务1:耗时10秒ThreadPoolTaskExecutor-4
任务3:耗时15秒ThreadPoolTaskExecutor-2
主函数耗时:15008
参考
https://blog.csdn.net/qq_41396619/article/details/81005084
https://blog.csdn.net/v2sking/article/details/72795742