Spring @Async vs Completable Future运行异步

时间:2018-12-20 10:07:16

标签: java spring spring-boot asynchronous

我可能一直在做某些错误的事情。所以,我有Spring的@Async

假设我有这段代码

@Async("poolbeanname") 
Function () {
     // some code 
}

我还有一个,假设我有这段代码

@Async("poolbeanname") 
Function () {
     CompletableFuture.runAsync{ new Runnable ()...} 
} 

现在我可以看到第二个代码,产生了一些线程,但是第一种方法似乎产生的线程不止一个?

3 个答案:

答案 0 :(得分:2)

要启用使用@Async,您应该使用@EnableAsync

  

让我们开始通过Java配置启用异步处理–只需将@EnableAsync添加到配置类即可:

@Configuration
@EnableAsync
public class SpringAsyncConfig { ... }

并且您必须使用从其他类调用的public方法:

  

@Async有两个限制:

     
      
  • 它必须仅应用于公共方法

  •   
  • 自调用–从同一类中调用async方法–不起作用

  •   

答案 1 :(得分:1)

@Async("poolbeanname") 
Function () {
}

如果配置类中有@EnableAsync,则以上代码段将使用线程池异步执行。

@Configuration
@EnableAsync

@SpringBootApplication
@EnableAsync

启用异步后,spring将搜索自定义taskExecutor或executor bean,如果找不到,则默认为其自己的taskExecutor。

检查您的日志中是否有Initializing ExecutorService....行 开箱即用的是,它说它初始化了o.s.s.concurrent.ThreadPoolTaskExecutor,默认情况下将为您提供1的核心池大小。

要覆盖执行程序,只需要将工厂方法添加到Executor的配置类中。

@Bean
public Executor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    threadPoolTaskExecutor.setCorePoolSize(10);
    threadPoolTaskExecutor.setMaxPoolSize(50);
    //etc...
    return threadPoolTaskExecutor;
}

如果执行程序被覆盖,则可能是指定了一个线程池大小或使用了Executors.newSingleThreadExecutor();

CompletableFuture:

代码CompletableFuture.runAsync{ new Runnable ()}将创建一个CompletableFuture实例,并在每次调用时异步执行该代码(创建线程)。

CompletableFuture<Void> future
  = CompletableFuture.runAsync(() -> "This is processed asynchronously");

答案 2 :(得分:0)

@ M.Deinum在他的评论中强调了这一点:

@Async("poolbeanname") 
Function () {
  CompletableFuture.runAsync{ new Runnable ()...} 
} 

除非您真正需要它,否则它是没有用的,因为:@Asyncpoolbeanname线程池中发送方法的执行,而CompletableFuture.runAsync{ new Runnable ()...}将从{{1} }。

您可以简单地执行以下操作:

poolbeanname

请注意,由于spring的对象代理,如果这样做:

@Async("poolbeanname") 
Function () {
  CompletableFuture.completedFuture( futureResult); 
} 

但是您可以通过自动注入bean来使用此解决方法。

@Service
class YourService {

   callAsyncFunction(){
      function(); //@Async will not work here 
   }

   @Async("poolbeanname") 
   function () {
      CompletableFuture.completedFuture( futureResult);
    } 
}