标签: completable-future

创建已完成的CompletableFuture <Void>的正确方法是什么

我在java 8中使用Completable future我想编写一个方法,根据接收到的参数,并行运行带有副作用的多个任务然后返回它们的"组合"未来(使用CompletableFuture.allOf()),或者什么都不做并返回一个已经完成的未来.

但是,allOf返回一个CompletableFuture<Void>:

public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
Run Code Online (Sandbox Code Playgroud)

并且创建已经完成的未来的唯一方法就是使用completedFuture(),它需要一个值:

public static <U> CompletableFuture<U> completedFuture(U value)
Run Code Online (Sandbox Code Playgroud)

返回已使用给定值完成的新CompletableFuture.

并且Void是不可实现的,所以我需要另一种方法来创建已经完成的类型未来CompletableFuture<Void>.

做这个的最好方式是什么?

java concurrency java-8 completable-future

13
推荐指数
2
解决办法
4510
查看次数

线程与CompletableFuture

将代码直接传递给线程vs使用CompletableFuture的优势是什么?

Thread thread = new Thread(() -> {do something});
thread.start();
Run Code Online (Sandbox Code Playgroud)

VS

CompletableFuture<Void> cf1 =  
     CompletableFuture.runAsync(() -> {do something}); 
Run Code Online (Sandbox Code Playgroud)

java multithreading java-8 completable-future

13
推荐指数
2
解决办法
2433
查看次数

Java 11 HTTP客户端异步执行

我正在尝试JDK 11中的新HTTP客户端API,特别是它执行请求的异步方式.但有些事情我不确定我理解(有点像实现方面).在文档中,它说:

在可行的CompletableFuture情况下,返回实例的异步任务和相关操作将在客户端提供的线程上执行Executor.

据我所知,这意味着如果我在创建HttpClient对象时设置自定义执行程序:

ExecutorService executor = Executors.newFixedThreadPool(3);

HttpClient httpClient = HttpClient.newBuilder()
                      .executor(executor)  // custom executor
                      .build();
Run Code Online (Sandbox Code Playgroud)

然后,如果我异步发送请求并在返回时添加依赖操作CompletableFuture,则依赖操作应在指定的执行程序上执行.

httpClient.sendAsync(request, BodyHandlers.ofString())
          .thenAccept(response -> {
      System.out.println("Thread is: " + Thread.currentThread().getName());
      // do something when the response is received
});
Run Code Online (Sandbox Code Playgroud)

但是,在上面的依赖操作(使用者中thenAccept)中,我看到执行它的线程来自公共池而不是自定义执行器,因为它打印Thread is: ForkJoinPool.commonPool-worker-5.

这是实施中的错误吗?或者我错过了什么?我注意到它说"实例是在客户端的执行程序提供的线程上执行的,在实际可行的情况下",这是不适用的情况?

请注意,我也尝试了thenAcceptAsync,结果相同.

java asynchronous http completable-future java-11

13
推荐指数
2
解决办法
1451
查看次数

在测试中模拟CompletionException

我有一个HttpClient具有返回功能的类CompletableFuture:

public class HttpClient {

  public static CompletableFuture<int> getSize() {
      CompletableFuture<int> future = ClientHelper.getResults()
                 .thenApply((searchResults) -> {
                    return searchResults.size();
                });

      return future;
   }
}
Run Code Online (Sandbox Code Playgroud)

然后另一个函数调用此函数:

public class Caller {

   public static void caller() throws Exception {
       // some other code than can throw an exception
       HttpClient.getSize()
       .thenApply((count) -> {
          System.out.println(count);
          return count;
       })
       .exceptionally(ex -> {
          System.out.println("Whoops! Something happened....");
       });
   }
}
Run Code Online (Sandbox Code Playgroud)

现在,我想写一个测试来模拟ClientHelper.getResults 失败,所以我写了这个:

@Test
public void myTest() {
    HttpClient mockClient = mock(HttpClient.class);

    try …
Run Code Online (Sandbox Code Playgroud)

java exception mockito completable-future

12
推荐指数
1
解决办法
2704
查看次数

CompletableFuture已完成,但有例外

CompletableFuture.completedFuture()返回CompletedFuture已使用给定值完成的.

我们如何构建一个CompletableFuture已经完成的异常?

意思是,我希望将来抛出一个异常,而不是返回一个值.

java exception-handling completable-future

12
推荐指数
2
解决办法
1162
查看次数

是否可以安排 CompletableFuture?

有没有办法在 Java 中安排 CompletableFuture?我想要做的是安排一个要延迟执行的任务,并在它完成时将它与其他要异步执行的操作链接起来。到目前为止,我没有找到任何方法来做到这一点。

对于好的 ol' Futures,我们有例如 ScheduledExecutorService,我们可以在其中安排一个任务以延迟执行,如下所示:

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
Future<String> future = scheduledExecutorService.schedule(() -> "someValue", 10, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

CompletableFutures 有没有类似的方法?

java concurrency scheduled-tasks completable-future

12
推荐指数
2
解决办法
6962
查看次数

在控制器中使用 @Async 和 CompletableFuture 可以提高我们 api 的性能吗?

我想要实现的是,通过以这种简单的方式使用多线程,在我的 RESTApi 控制器中使用 @Async 和 CompletableFuture 可以获得更好的性能吗?

这是我所做的,这是我的控制器:

@PostMapping("/store")
@Async
public CompletableFuture<ResponseEntity<ResponseRequest<CategoryBpsjResponseDto>>> saveNewCategoryBPSJ(@Valid @RequestBody InputRequest<CategoryBPSJRequestDto> request) {
    
    CompletableFuture<ResponseEntity<ResponseRequest<CategoryBpsjResponseDto>>> future = new CompletableFuture<>();

    future.complete(ResponseEntity.ok(new ResponseRequest<>("Okay", categoryBPSJService.save(request))));
    return future;
}
Run Code Online (Sandbox Code Playgroud)

VS

@PostMapping("/store")
public ResponseEntity<ResponseRequest<CategoryBpsjResponseDto>> saveNewCategoryBPSJ(@Valid @RequestBody InputRequest<CategoryBPSJRequestDto> request) {
    
    return ResponseEntity.ok(new ResponseRequest<>("okay", categoryBPSJService.save(request));
}
Run Code Online (Sandbox Code Playgroud)

正如你在我的第一个控制器函数中看到的,我在我的函数响应中添加了 CompletableFuture,但是在我的服务中,我在这一行中保存的categoryBPSJService.save(request)不是异步的,只是一个看起来像这样的简单函数:

public CategoryBpsjResponseDto save(InputRequest<CategoryBPSJRequestDto> request) {
    CategoryBPSJRequestDto categoryBPSJDto = request.getObject();

    Boolean result = categoryBPSJRepository.existsCategoryBPSJBycategoryBPSJName(categoryBPSJDto.getCategoryBPSJName());

    if(result){
        throw new ResourceAlreadyExistException("Category BPSJ "+ categoryBPSJDto.getCategoryBPSJName() + " already exists!");
    }

    CategoryBPSJ categoryBPSJ = new CategoryBPSJ();
    categoryBPSJ = map.DTOEntity(categoryBPSJDto);

    categoryBPSJ.setId(0L); …
Run Code Online (Sandbox Code Playgroud)

java performance spring asynchronous completable-future

12
推荐指数
1
解决办法
1279
查看次数

在定义API时我应该返回CompletableFuture还是Future?

在Java 8中,接口或抽象类更好地定义API返回CompletableFuture而不是返回Future?考虑到它是丑陋转化FutureCompletableFuture和事实CompletableFuture将会给调用者直接使用功能的风格更加灵活,这可能是一个API只返回一个很好的理由Future

java future interface java-8 completable-future

11
推荐指数
1
解决办法
1694
查看次数

使用与CompletableFuture的默认公共fork/join池进行长时间阻塞调用是不好的做法吗?

假设我有一个CompletableFuture,它包含一个阻塞调用,比如使用JDBC查询后端.在这种情况下,由于我没有将任何执行程序服务作为参数传递给CompletableFuture.supplyAsync(),因此通过后端获取资源的实际阻塞工作应该由公共Fork/Join池中的线程完成.让来自普通FJpool的线程阻塞调用不是不好的做法吗?我在这里的优点是我的主线程没有阻塞,因为我委托阻塞调用异步运行.在这里检查abt JDBC调用是否阻塞.如果这个推论是正确的,为什么可以选择使用带有CompletableFuture的默认公共FJpool?

CompletableFuture<List<String>> fetchUnicorns  = 
    CompletableFuture.supplyAsync(() -> {
        return unicornService.getUnicorns();
    });

fetchUnicorns.thenAccept(/**Do something with the result*/);
Run Code Online (Sandbox Code Playgroud)

java asynchronous java-8 completable-future

11
推荐指数
2
解决办法
3320
查看次数

任何相当于Kotlin的延期

Coroutine async返回Deferred<T>,有懒惰执行和等待用法的例子.

但是,我们如何等待任何一个Deffered实例完成?

简而言之

  // whats the equivalent of CompletableFuture.anyOf(...)?
  // is this how we do it? if so how costly is this?
  select<Unit> {
     deffered1.onAwait {}
     deffered2.onAwait {}
  }
Run Code Online (Sandbox Code Playgroud)

coroutine kotlin completable-future

10
推荐指数
1
解决办法
453
查看次数