Spring注解@EnableAsync @Async

阅读数:95 评论数:0

跳转到新版页面

分类

python/Java

正文

我们要使用多线程的时候,往往需要创建Thread类,或者实现Runnable接口,如果使用线程池,我们还需要创建Executors,在使用Spring中,只要@EnableAsync就可以使用多线程,使用@Async就可以定义一个线程任务。通过Spring给我们提供的ThreadPoolTaskExecutor就可以使用线程池。

默认情况下,Spring将搜索相关的线程池定义:要么在上下文中搜索唯一的TaskExecutor bean,要么搜索名为“taskExecutor”的Executor bean。如果两者都无法解析,则将使用SiimpleAsyncTaskExecutor来处理异步方法调用。

1、定义配置类

@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
	
	private static final int corePoolSize = 10;       		// 核心线程数(默认线程数)
	private static final int maxPoolSize = 100;			    // 最大线程数
	private static final int keepAliveTime = 10;			// 允许线程空闲时间(单位:默认为秒)
	private static final int queueCapacity = 200;			// 缓冲队列数
	private static final String threadNamePrefix = "Async-Service-"; // 线程池名前缀
	
	@Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名
	public ThreadPoolTaskExecutor getAsyncExecutor(){
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(corePoolSize);   
		executor.setMaxPoolSize(maxPoolSize);
		executor.setQueueCapacity(queueCapacity);
		executor.setKeepAliveSeconds(keepAliveTime);
		executor.setThreadNamePrefix(threadNamePrefix);
		
		// 线程池对拒绝任务的处理策略
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		// 初始化
		executor.initialize();
		return executor;
	}
}

@EnableAsync开始对异步任务的支持。线程宾的配置还有另外一种方式,就是直接实现AsyncConfigurer接口,重写getAsyncExecutor方法。

@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {

     @Override
     public Executor getAsyncExecutor() {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         executor.setCorePoolSize(7);
         executor.setMaxPoolSize(42);
         executor.setQueueCapacity(11);
         executor.setThreadNamePrefix("MyExecutor-");
         executor.initialize();
         return executor;
     }

     @Override
     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
         return new MyAsyncUncaughtExceptionHandler();
     }
}

2、定义异步任务

@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可以加在方法或者类上,加在类上表示这整个类都使用这个自定义线程池操作。

然后可以用@Autowired注入这个service,进行调用。

注意如下方式会使@Async失效:

(1)异步方法使用static修饰。

(2)异步类没有使用@Component注解(或其他注解),导致spring无法扫描到异步类。

(3)使用@Async时,不关心结果,即不能有返回值。

 




相关推荐

(1)Spring MVC是一个基于DispatcherServlet的MVC框架,DispatcherServlet是继承自HttpServlet的。Spring的IOC和AOP主要就用了java的

如果一个类交张spring管理,比如 &lt;bean id="foo1" class="demo.scope.foo" /&gt; 不指明scope就是单例。</p

@PathParam的声明允许你在URI路径中去映射你的方法将使用的参数。 @Path("/library") pu

方式1:通过@PostConstruct和@PreDestroy方法。 从Java EE5开始,Servlet增加了两个影响Servlet生命周期的注解。 方式2:通

一、概述 1、spring容器 spring中有三种bean容器:BeanFactory、ApplicationContext、WebApplicationContext。 (1)BeanFactor

有时我们在做开发的时候需要记录每个任务执行时间,或者记录一段代码执行时间,最简单的方法就是打印当前时间与执行完时间的差值,然后这样如果执行大量测试的话就很麻烦,并且不直观,如果想对执行的时间做进

一、request uri部分 @PathVariable 获取路径参数,形如url/{id} 二、request header部分 @RequestHeade

一、概述 springboot中有两种方式使用kafka时,直接使用kafka-client连接kafka服务;另一种是使用spring-kafka框架来连接kafka。 1、版本兼容 使用时要注意版

当然可以自己写redis的工具类,或者使用第三方开源jar包或代码,这里使用spring boot的集成类。 一、pom依赖 <dependency> <gro

websocket协议基于tcp的网络协议,它实现浏览器与器全双工通信。 spring boot2 +websocket 1、添加依赖 <pre clas