Java 如何在Spring Boot@Async中使用ForkJoinPool?
我想在我的spring boot项目中使用ForkJoinPool和@Async注释,比如ThreadPoolTaskExecutor 例如:-Java 如何在Spring Boot@Async中使用ForkJoinPool?,java,spring,spring-boot,java.util.concurrent,forkjoinpool,Java,Spring,Spring Boot,Java.util.concurrent,Forkjoinpool,我想在我的spring boot项目中使用ForkJoinPool和@Async注释,比如ThreadPoolTaskExecutor 例如:- @Bean("threadPoolTaskExecutor") public TaskExecutor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoo
@Bean("threadPoolTaskExecutor")
public TaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(1000);
executor.setThreadNamePrefix("Async-");
return executor;
}
我在代码中使用此链接,但我希望像这样使用ForkJoinPool。在我看来,您不能将
@Async
注释与ForkJoinPool
类结合使用ForkJoinPool
专用于将一个任务拆分为子任务,以并行方式执行它并将其合并到结果中。并行流是ForkJoinPool
幕后的。要使用ForkJoinPool
执行任务,您需要实现RecursiveTask
或RecursiveAction
接口。我不知道我们如何一起使用这些东西。要启用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");
}
可以将ForkJoinPool与asynch一起使用。这种方法并不是ForkJoinPool设计的目的——它解决分治任务并使用工作窃取算法,而是执行事件样式或IO阻塞任务,这是一个有效的用例 因此,使用基本用法,您可以:
CompletableFuture.runAsync(() -> doSomething(), ForkJoinPool.commonPool());
您还可以在异步模式下创建自定义ForkJoinPool。在异步模式下,ForkJoinPool中的工作者以FIFO(先进先出)顺序处理任务。默认情况下,ForkJoinPool按后进先出的顺序处理此类任务。此外,异步模式设置仅涉及从未加入的分叉任务。可用于已提交但从未加入的事件样式任务(针对其副作用执行的任务,而不是返回将由分叉任务处理然后加入的结果)
您可以在异步模式下创建具有给定并行性的自定义ForkJoinPool,如下所示(第一个参数是pool size,last-bool asyncMode):
因此,您所追求的是:
@Bean("threadPoolTaskExecutor")
public Executor getAsyncExecutor() {
ForkJoinPool pool = new ForkJoinPool(
6, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
return pool;
}
我不知道您为什么要这样做,但您仍然可以使用
ForkJoinPool
进行@Async
,因为ForkJoinPool
正在实现执行器的类
但是如果我们看一下,我看不到任何设置线程池大小的方法,使用它是有风险的
配置
@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
所有没有显式执行器参数的异步方法都使用ForkJoinPool.commonPool()执行(除非它不支持至少两个并行级别,在这种情况下,将创建一个新线程来运行每个任务)
感谢回复,ThreadPoolTaskExecutor和ForkJoinPool都使用ExecutorService接口。是的,两者都实现了ExecutorService
接口,但是@Async
注释的执行器需要通过实现TaskExecutor
接口,该接口由ThreadPoolTaskExecutor
实现,但是不是通过ForkJoinPool
。谢谢你的回复,但是我想像“yoursecifictaskexecutor”那样使用ForkJoinPool来创建bean,那么你能帮助我在Spring Boot中使用ForkJoinPool异步创建方法吗?为什么要使用ForkJoinPool?
ForkJoinPool-1-worker-1