我有遗嘱执行人,
@Bean("someExecutor")
public Executor someExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("AsyncMethod-");
executor.initialize();
return executor;
}
和异步方法。
@Async("someExecutor")
public Future<List<String>> someMethod(){
return CompletableFuture.supplyAsync(() -> {
//long time job
return listGeneratedByLongTimeJob;
});
}
Spring将对someMethod使用someExecutor吗?又如何?
我知道supplyAsync(supplier)的重载方法是supplyAsync(supplier,executor),下面的代码怎么样?
@Autowired("someExecutor")
private Executor executor;
@Async()
public Future<List<String>> someMethod(){
return CompletableFuture.supplyAsync(() -> {
//long time job
return listGeneratedByLongTimeJob;
}, executor);
}
谢谢。
答案 0 :(得分:1)
好吧,花点时间才能弄清楚这一点,在进入两种情况之前,我们需要讨论{
"name": "todo-list",
"version": "0.1.0",
"description": "Add and remove items from a list",
"author": "Crystal",
"private": true,
"dependencies": {
"express": "^4.16.4",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1",
"react-signup-login-component": "^1.2.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"babel-loader": "^8.0.4",
"cypress": "^3.1.3"
}
}
来自java.util.concurrent.CompletableFuture docs
所有没有显式Executor参数的异步方法都是使用ForkJoinPool.commonPool()执行的(除非它不支持并行度至少为两个,在这种情况下,将创建一个新的线程)运行每个任务)。为了简化监视,调试和跟踪,所有生成的异步任务都是标记接口CompletableFuture.AsynchronousCompletionTask的实例。
因此,当您每次调用ForkJoinPool
时,供应商将由CompletableFuture.supplyAsync(Supplier s)
线程执行,现在让我们开始案例1
案例1:
为清楚起见,我添加了一些ForkJoinPool
语句以打印线程名称
sysout
输出:
@Async("someExecutor")
public Future<String> asyncService() {
System.out.println();
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
System.out.println();
return CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
return "hello";
});
}
在这种情况下,AsyncMethod-1 - java.lang.ThreadGroup[name=main,maxpri=10]
ForkJoinPool.commonPool-worker-1 - java.lang.ThreadGroup[name=main,maxpri=10]
由asyncService()
线程执行,并且
AsyncMethod-1
中的provider由supplyAsync()
情况2:
ForkJoinPool
输出:
@Autowired
private Executor someExecutor;
@Async
public Future<String> asyncService() {
System.out.println();
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
System.out.println();
return CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
return "hello";
},someExecutor);
}
在第二种情况下,AsyncMethod-1 - java.lang.ThreadGroup[name=main,maxpri=10]
AsyncMethod-2 - java.lang.ThreadGroup[name=main,maxpri=10]
中的方法asyncService()
和供应商都使用来自supplyAsync()
的线程
默认情况下,Spring使用SimpleAsyncTaskExecutor实际运行这些someExecutor pool
方法,但是我们在配置中使用async
docs覆盖了someExecutor
默认情况下,Spring将搜索关联的线程池定义:上下文中的唯一TaskExecutor bean,否则为名为“ taskExecutor”的Executor bean。如果二者都不可解决,则将使用SimpleAsyncTaskExecutor处理异步方法调用。
注意::如果您在配置类中没有@EnableAsync
,则会得到不同的结果,我将在gitHub中上传此代码并在此处添加链接