问题
在项目中在某个方法上使用@Async 注解,但是发现调用这个方法的时候,并没有使用异步调用,而是同步。
经过排查需要注意:
- 需要在@Async 注解的类或者启动类Application中使用@EnableAsync注解。
- @Async注解的函数,跟调用这个异步函数的函数不要在同一类中。
- 不要自己使用new创建异步函数所在的类对象,而是需要通过Spring bean自动注入。
- 异步函数所在的类需要使用@Component 或者其它的注解加入到Spring bean中。
附上代码
线程池配置
@Configuration
public class ThreadPoolConfig {
public static final String THREAD_NAME_PREFIX = "async-executor-";
public static final Integer CORE_POOL_SIZE = 30;
public static final Integer MAX_POOL_SIZE = 40;
public static final Integer QUEUE_CAPACITY = 200;
@Bean(name = "asyncThreadExecutor")
@Primary
public Executor AsyncExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(CORE_POOL_SIZE);
executor.setMaxPoolSize(MAX_POOL_SIZE);
executor.setQueueCapacity(QUEUE_CAPACITY);
executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
//设置线程池的拒绝策略,当线程池和队列已满时,异步变成同步
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
异步函数所在的类
@Component
@EnableAsync
public class AysncTest {
@Async("asyncThreadExecutor")
public void testAysnc(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testAysnc:"+System.currentTimeMillis());
System.out.println("testAysnc-thread:"+Thread.currentThread().getName());
}
}
调用
@RestController
public class Hello {
@Autowired
public AysncTest aysncTest;
@GetMapping("/test")
public String test(){
System.out.println("test1:"+System.currentTimeMillis());
aysncTest.testAysnc();
System.out.println("test2:"+System.currentTimeMillis());
System.out.println("test-thread:"+Thread.currentThread().getName());
return "Hello";
}
}