一、Spring异步注解阻塞
Spring异步注解是提高程序效率的重要手段之一,但是如果不合理使用,也会带来阻塞问题。比如,如果在使用Spring异步注解时,注解了过多的方法或者使用了分段锁,就会导致性能反而下降。
@Async
public Future<Void> computeAsync() {
return CompletableFuture.completedFuture(null);
}
为了避免Spring异步注解阻塞,可以采取以下措施:
1.合理控制异步请求的个数,以充分利用资源提高效率;
2.使用分布式锁代替分段锁;
3.使用异步队列等辅助类提高处理效率。
二、Spring异步注解有什么弊端
Spring异步注解虽然可以提高程序效率,但也存在一些弊端:
1.异步调用可能导致程序执行顺序与代码编写顺序不一致,导致程序逻辑异常;
2.当异步执行的任务执行时间过长,可能导致线程池的拥堵等问题;
3.因为异步调用是在新的线程中执行,所以在异步调用过程中,线程上下文不能被当做请求上下文传递。
三、Spring异步注解怎么实现
Spring异步注解的实现主要依赖于两个核心类:
1. AsyncAnnotationBeanPostProcessor:用于处理Bean中标注@Async注解的方法,生成异步执行代理;
2. AsyncExecutionInterceptor:用于创建执行异步任务的Runnable实例。
具体实现方法如下:
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(2000);
executor.setThreadNamePrefix("async-thread-");
executor.initialize();
return executor;
}
}
@Service
public class AsyncService {
@Async
public Future<String> doSomeLongOperation() {
//long operation
return CompletableFuture.completedFuture(result);
}
}
public class AsyncAction {
private AsyncService asyncService;
//调用异步方法并获得结果
public void doAction() {
Future<String> result = asyncService.doSomeLongOperation();
//...
}
}
四、Spring异步注解原理
Spring异步注解的原理是通过AOP技术,对被@Async注解标记的方法,进行拦截并创建异步代理,然后将异步调用转发到线程池执行,最后返回Future对象以便其它方法继续执行。
五、Spring异步注解不生效
Spring异步注解不生效的原因主要有以下几点:
1.项目没有开启异步执行支持,需要@EnableAsync注解
2.方法没有被public修饰;
3.在同一个类中调用异步方法,没有使用self调用,导致代理失效。
六、Spring开启异步注解
Spring开启异步注解需要通过@EnableAsync注解来开启,并且需要通过@Configuration类中覆盖AsyncConfigurerSupport类的getAsyncExecutor方法来配置线程池(可选)。
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(2000);
executor.setThreadNamePrefix("async-thread-");
executor.initialize();
return executor;
}
}
七、Spring异步注解是什么
Spring异步注解是标记一个方法会被异步调用的注解。在方法上加上@Async注解,使其可以被多线程执行,从而提高程序的效率。
八、Spring异步注解使用场景
Spring异步注解非常适合处理长时间耗时的任务,例如大文件读取、大数据处理、网络IO等。
九、Spring异步注解事务不起作用
Spring事务管理默认是基于线程的,即同一个线程中的各个事务共享同一个连接和事务,但是如果在异步调用中开启了新的线程,那么事务就无法在新线程中被识别,因此在使用Spring异步注解时,需要注意事务的传播属性,可以在注解中指定PROPAGATION_REQUIRES_NEW级别的传播行为来实现异步调用时的事务管理。
@Service
public class AsyncService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Async
public Future<String> doSomeLongOperation() {
//long operation
return CompletableFuture.completedFuture(result);
}
}
附:SpringBoot异步注解示例
对于SpringBoot项目,使用异步注解的方法与普通Spring项目一致,只需要在SpringBoot的启动类中使用@EnableAsync注解,然后在需要异步执行的方法上使用@Async注解即可。
@SpringBootApplication
@EnableAsync
public class Application {
//...
}