SpringBoot's @EnableAsync@Async usage summary

When we use multithreading, we often need to create a Thread class or implement the Runnable interface. If we want to use the thread pool, we also need to create Executors. In the use of spring, we have given us good support. Multi-threading can be used as long as @EnableAsync is required. Use @Async to define a thread task. The thread pool can be used through the ThreadPoolTaskExecutor provided by spring.

By default, Spring will search for the relevant thread pool definition: either for the only TaskExecutor bean in the context, or for an Executor bean named "taskExecutor". If neither can be resolved, a SimpleAsyncTaskExecutor will be used to handle the asynchronous method call.

1. Steps to use

(1) Define the configuration class

@EnableAsync starts to support asynchronous tasks

@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;
	}
}

(2) Define the service method

The @Async annotation declares one or more asynchronous tasks, which can be added to a method or class, and added to a class indicates that the entire class uses this custom thread pool for operations

@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------------");
 
	}
}

(3) test

Create a control class, @Autowired this service, call these two methods twice, and the running result is:

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

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

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

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

It can show that our asynchronous operation is successful

2. @Async failure scenarios and precautions
1. The asynchronous method is decorated with static
2. The asynchronous class is not injected into the ioc container, so spring cannot scan the asynchronous class
3. The asynchronous method cannot be in the same class as the asynchronous method
4. Calling @Async requires Use annotations such as @Autowired or @Resource to automatically inject, and you cannot manually new objects yourself.
5. If you use the SpringBoot framework, you must add the @EnableAsync annotation to the startup class.
6. It is useless to mark @Transactional on the Async method. It is valid to mark @Transactional on the method called by the Async method.
7. The caller of the method marked by @Async cannot be in the same class as the called method, otherwise it will not work. 8.
When using @Async, the requirement is that there should be no return value, otherwise an error will be reported because the asynchronous requirement is not concerned result

Guess you like

Origin blog.csdn.net/w20001118/article/details/127921572