我想在Spring Boot项目中使用带有ThreadPoolTaskExecutor之类的@Async注释的ForkJoinPool
例如:-
@Bean("threadPoolTaskExecutor")
public TaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(1000);
executor.setThreadNamePrefix("Async-");
return executor;
}
我在代码中使用https://dzone.com/articles/spring-boot-creating-asynchronous-methods-using-as此链接,但我想这样使用ForkJoinPool。
答案 0 :(得分:3)
我认为您不能将@Async
注释与ForkJoinPool
类结合使用。 ForkJoinPool
致力于将一个任务拆分为子任务,以并行方式执行该任务并将其合并为结果。后台有using ForkJoinPool
个并行流。要使用ForkJoinPool
执行任务,您需要实现RecursiveTask
或RecursiveAction
接口。我没有见过如何一起使用这些东西的方法。
答案 1 :(得分:1)
最好将Asknch与ForkJoinPool一起使用。这种方法并非完全是ForkJoinPool设计的目的-解决分而治之的任务并使用工作窃取算法,而是执行事件样式或IO阻止任务,这是一个有效的用例。
因此,通过基本用法,您可以执行以下操作:
CompletableFuture.runAsync(() -> doSomething(), ForkJoinPool.commonPool());
您还可以在Asynch模式下创建自定义ForkJoinPool。异步模式下的ForkJoinPool中的工作人员以FIFO(先进先出)顺序处理任务。默认情况下,ForkJoinPools以LIFO(后进先出)顺序处理此类任务。另外,异步模式设置仅涉及从未加入的分叉任务。可以用于已提交但从未加入的事件式任务(执行的任务具有副作用,而不是返回将由派生任务处理然后加入的结果)。
您可以像这样在异步模式下创建具有给定并行性的自定义ForkJoinPool(第一个参数是池大小,最后一个-bool asyncMode):
ForkJoinPool pool = new ForkJoinPool(
6, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
所以你追求的是:
@Bean("threadPoolTaskExecutor")
public Executor getAsyncExecutor() {
ForkJoinPool pool = new ForkJoinPool(
6, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
return pool;
}
答案 2 :(得分:1)
我不知道您为什么要这样做,但是您仍然可以对ForkJoinPool
使用@Async
,因为ForkJoinPool
正在实现Executor
的类
但是,如果我们查看ForkJoinPool-documentation,我看不到任何设置线程池大小的方法,那么使用它是您的风险。
配置
@Bean("threadPoolTaskExecutor")
public Executor getAsyncExecutor() {
ForkJoinPool pool = new ForkJoinPool();
return pool;
}
服务
@Async("threadPoolTaskExecutor")
public void testRun() {
System.out.println(Thread.currentThread().getName());
}
输出
ForkJoinPool-1-worker-1
如果您非常想使用ForkJoinPool
,请使用CompletableFuture.async
方法而不是spring boot @Async
docs
所有没有显式Executor参数的异步方法都是使用ForkJoinPool.commonPool()执行的(除非它不支持并行度至少为2,在这种情况下,将创建一个新的线程来运行每个任务)>
答案 3 :(得分:0)
要启用Spring的异步方法执行功能,您可以在配置类中使用@EnableAsync
批注。
@Configuration
@EnableAsync
public class ThreadConfig {
@Bean
public TaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(4);
executor.setThreadNamePrefix("prate");
executor.initialize();
return executor;
}
}
在某些情况下,您不希望同一线程池运行该应用程序的所有任务。您可能需要具有不同配置的单独线程池来支持我们的功能。
因此,您可以配置特定的ThreadPoolExecutor
,例如-
@Configuration
@EnableAsync
public class ThreadConfig {
@Bean(name = "specificTaskExecutor")
public TaskExecutor specificTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.initialize();
return executor;
}
}
现在,该函数应设置限定符值,以确定特定执行程序或TaskExecutor的目标执行程序。
@Async("specificTaskExecutor")
public void runFromAnotherThreadPool() {
System.out.println("test here");
}