spring注解@EnableAsync@Async实现多线程
通过spring给我们提供的ThreadPoolTaskExecutor就可以使,例子如下:
首先定义配置类
package com.andong.spring.test;
import java.util.concurrent.Executor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.backportconcurrent.ThreadPoolTaskExecutor;
@Configuration
@ComponentScan("com.andong.test")
@EnableAsync // 启用异步任务
public class ThreadConfig {
@Bean // 执行需要依赖线程池,配置一个线程池
public Executor getExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setThreadNamePrefix("Async-Executor");
threadPoolTaskExecutor.setCorePoolSize(5);
threadPoolTaskExecutor.setMaxPoolSize(10);
threadPoolTaskExecutor.setQueueCapacity(25);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
定义要执行的任务
package com.andong.spring.test;
import java.util.Random;
import java.util.UUID;
import org.springframework.scheduling.annotation.Async;
import com.alibaba.dubbo.config.annotation.Service;
@Service
public class AsynTaskExecuteService {
@Async // 这里进行标注为异步任务,在执行此方法的时候,会单独开启线程来执行
public void f1() {
System.out.println("f1 : " + Thread.currentThread().getName() + " " + UUID.randomUUID().toString());
try {
Thread.sleep(new Random().nextInt(100));
} catch (Exception e) {
e.printStackTrace();
}
}
@Async
public void f2() {
System.out.println("f2 : " + Thread.currentThread().getName() + " " + UUID.randomUUID().toString());
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.测试类
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ThreadConfig.class);
AsynTaskExecuteService service = context.getBean(AsynTaskExecuteService.class);
for (int i = 0; i < 5; i++) {
service.f1(); // 执行异步任务
service.f2();
}
context.close();
}
输出结果
f1 : ThreadPoolTaskExecutor-5 20e6ba88-ae51-42b9-aac6-ed399419fe6d
f2 : ThreadPoolTaskExecutor-2 0d7b1da4-e045-4d58-9054-e793f931cae1
f2 : ThreadPoolTaskExecutor-4 17b8d7c7-24e3-4bcf-b4da-822650a8f0be
f1 : ThreadPoolTaskExecutor-3 a9b32322-1c9b-4fc7-9c2a-1f7a81f2b089
f1 : ThreadPoolTaskExecutor-1 13a85fde-73c7-4c9b-9bb2-92405d1d3ac4
f2 : ThreadPoolTaskExecutor-3 8896caaf-381c-4fc3-ab0f-a42fcc25e5fd
f1 : ThreadPoolTaskExecutor-5 48246589-f8e9-4e9c-b017-8586bf14c0b0
f2 : ThreadPoolTaskExecutor-1 291b03ea-154f-46ba-bc41-69a61d1dd4d5
f1 : ThreadPoolTaskExecutor-4 856d8f48-70b4-475a-80cc-27d1635be36b
f2 : ThreadPoolTaskExecutor-2 1f7b1918-cf10-49a3-aaec-7b97a3a67e7d
可以看到我们两个任务是异步进行的。
下面关于线程池的配置还有一种方式,就是直接实现AsyncConfigurer接口,重写getAsyncExecutor方法即可,代码如下
package com.andong.spring.test;
import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@ComponentScan
@EnableAsync
public class ThreadConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
// TODO Auto-generated method stub
return null;
}
}