SpringBoot实践之---@EnableAsync和@Async 线程池自定义和使用

    自定义线程池的配置类  AsyncConfig

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
/** 
* @Description: 自定义线程池的配置类,并在类上添加@EnableAsync 注解,
 * 然后在需要异步的方法上使用@Async("线程池名称") 该方法就可以异步执行了
* @Param:  * @param null 
* @return:  
* @Author: wenliang 
* @Date: 2019/11/6 
**/ 
public class AsyncConfig {
	private static final Logger logger = LoggerFactory.getLogger(AsyncConfig.class);
	@Bean("taskExecutor") // bean的名称,,不写的里面值,则默认为首字母小写的方法名
	public TaskExecutor taskExecutor() {
		logger.info("start asyncServiceExecutor");
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		int core = Runtime.getRuntime().availableProcessors();
		//配置核心线程数
		executor.setCorePoolSize(core);
		//配置最大线程数
		executor.setMaxPoolSize(core * 2 + 1);
		// 允许线程空闲时间(单位:默认为秒)
		executor.setKeepAliveSeconds(5);
		//配置队列大小
		executor.setQueueCapacity(9999);
		//配置线程池中的线程的名称前缀
		executor.setThreadNamePrefix("async-service-");

		// rejection-policy:当pool已经达到max size的时候,如何处理新任务
		// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.setWaitForTasksToCompleteOnShutdown(true);
		//执行初始化
		executor.initialize();
		return executor;
	}

}

注① @Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

注② @EnableAsync开始对异步任务的支持

接着写个service类 testAsyncService :
 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
 
@Service
public class testAsyncService {
	Logger log = LoggerFactory.getLogger(testAsyncService.class);
 
	// 发送提醒短信 1
	@Async("taskExecutor")
	public void service1() throws InterruptedException {
		log.info("--------start-service1------------");
		Thread.sleep(5000); // 模拟耗时
	    log.info("--------end-service1------------");
	}
	
	// 发送提醒短信 2
	@Async("taskExecutor")
	public void service2() throws InterruptedException {
		
		log.info("--------start-service2------------");
		Thread.sleep(2000); // 模拟耗时
	    log.info("--------end-service2------------");
 
	}

注① 使用@Async注解来声明一个或多个异步任务,可以加在方法或者类上,加在类上表示这整个类都是使用这个自定义线程池进行操作

接着我们可以创建control类@Autowired这个service并且调用这其中两个方法,进行连续调用,会发现运行结果是

     --------start-service1------------

     --------start-service2------------

     --------end-service2------------

     --------end-service1------------

可以说明我们的异步运行成功了

注意点:

一、异步方法使用static修饰
二、异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
三、类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
五、如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解
 

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页