SpringBoot学习--异步接口的配置和调用

SpringBoot学习–异步接口的配置和调用

总体概述

  1. 搭建基础SpringBoot环境。
  2. 添加异步配置类AsyncConfig.java。
  3. 添加测试Controller。
  4. 添加测试Service。
  5. 使用@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

  1. @Configuration注解为配置类
  2. @EnableAsync开启异步
  3. 继承AsyncConfigurer类
  4. 设置线程相关参数
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

项目GIT地址

https://gitee.com/flygoa/springbootdemo1.git

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-贫寒豌豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值