异步执行

部分代码来自《spring cloud 微服务 入门、进阶与实战》

简单使用

spring 中想要方法是异步执行只需要加上@Async注解即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Component
public class MyAsyncMethod {
@Async
public void test1() throws InterruptedException {
int i = 0;
while (i<5){
System.out.println(i);
i++;
}
}
public void test2() throws InterruptedException {
System.out.println("test222222");
Thread.sleep(10L);
System.out.println("test333333");
}
}
1
2
myAsyncMethod.test1();
myAsyncMethod.test2();

控制台输出

1
2
3
4
5
6
7
test222222
0
1
2
3
4
test333333

配置线程池

有时我们想要自定义线程池的参数我们可增加如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
@ConfigurationProperties(prefix = "spring.task.pool")
public class TaskThreadPoolConfig {

/**核心线程数*/
private int corePoolSize = 5;

/**最大线程数*/
private int maxPoolSize = 50;

/**线程池维护线程所允许的空闲时间*/
private int keepAliveSeconds = 60;

/**队列长度*/
private int queueCapacity = 10000;

/**线程名称前缀*/
private String threadNamePrefix = "FSH-AsyncTask-";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Configuration
public class AsyncTaskExecutePool implements AsyncConfigurer {
private Logger logger = LoggerFactory.getLogger(AsyncTaskExecutePool.class);

@Autowired
private TaskThreadPoolConfig config;

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(config.getCorePoolSize());
executor.setMaxPoolSize(config.getMaxPoolSize());
executor.setQueueCapacity(config.getQueueCapacity());
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
executor.setThreadNamePrefix(config.getThreadNamePrefix());
/**
* 线程池拒绝策略:如果不配置并超过了负荷会造成溢出
* AbortPolicy:直接抛出异常 会丢弃任务
* CallerRunsPolicy 先由主线程执行当前任务,下个任务继续交给线程池来执行
*/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
// 异步任务中异常处理
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {

logger.error("==========================" + arg0.getMessage() + "=======================", arg0);
logger.error("exception method:" + arg1.getName());
}
};
}
}

然后在配置文件中配置相关参数

1
spring.task.pool.corePoolSize=9

注意

1
异步执行方法需在外部调用,在异步类中通过 this.xxx() 方式调用会无效