看到項目中有使用到Async注解和completetableFuture的runApply方法的使用。兩者都是異步提交方法的方式。那他两都分别在什么场景底下比较适用呢?
为了使得异步可用,Spring提供了一个注解@EnableAsync如果Java的配置文件标注他,那么Spring就会开启同步可用,这样就可以使用注解@Async驱动Spring使用的异步调用,其中的默认线程池也就是AsyncTaskExecutor,默认参数为无限大(首先简单百度了下,网上提到@Async默认异步配置使用的是SimpleAsyncTaskExecutor,该线程池默认来一个任务创建一个线程,在大量的请求的时候,这时就会不断创建大量线程,极有可能压爆服务器内存。如下面的测试情况,无限创建线程) 使用Java配置demo:
package com springboot chapterl3.config
/**** imports ******/
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
//定义线程池
Override
public Executor getAsyncExecutor () {
//定义线程池
ThreadPoolTaskExecutor taskExecutor =new ThreadPoolTaskExecutor();
//核心线程数
taskExecutor setCorePool ze (10);
//线程池最大线程数
taskExecutor setMaxPoolS ze (30) ;
//线程队列最大线程数
taskExecutor . setQueueCapacity(2000) ;
//初始化
taskExecutor.initialize();
return taskExecutor;
}
}
点击:https://blog.csdn.net/weixin_40413961/article/details/107703172
使用CompleteTableTuture demo
/**
* @author yuanxindong
* @date: 2020/7/31 16:53
*/
@Service
public class AsyncTest {
@Autowired
AsycMethodDemo asycMethodDemo;
@Test
public void runAsyncTask() throws InterruptedException {
Thread.sleep(50000);
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
AsycMethodDemo asycMethodDemo = applicationContext.getBean(AsycMethodDemo.class);
Integer i = 0;
for (i = 0; i < 100; i++) {
getTask(asycMethodDemo, i);
}
Thread.sleep(1000000);
}
private void getTask(AsycMethodDemo asycMethodDemo, Integer i) {
try {
CompletableFuture.runAsync(() -> {
try {
asycMethodDemo.asyncMethod(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
} catch (Exception e) {
}
}
}
运行结果:
除了主线程,根据图看到一共起了8个线程。是的forkJoinPool的默认核心线程数是根据CPU的核数来穿建的
/**
* @author yuanxindong
* @date: 2020/7/31 16:53
*/
@Service
public class AsyncTest {
@Autowired
AsycMethodDemo asycMethodDemo;
@Test
public void runAsyncTask() throws InterruptedException {
Thread.sleep(50000);
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
AsycMethodDemo asycMethodDemo = applicationContext.getBean(AsycMethodDemo.class);
int i = 0;
for( i = 0; i< 100;i++){
asycMethodDemo.asyncMethod(i);
System.out.println("任务"+i+"执行完成");
}
Thread.sleep(1000000);
}
}
运行结果:
可以看出,一共起了100个线程,由于线程起的多可以明显看到这几个任务执行完成的真的很快,这也就是传说中的时间并行执行吧,但是这里会有 一个问题那就是如果任务真的超级多的话,会不会爆掉。
个人感觉Java 8的completeTable比较好用一些,也支持自定义。