Home  >  Article  >  Java  >  How to use CompletableFuture function in Java for asynchronous programming

How to use CompletableFuture function in Java for asynchronous programming

王林
王林Original
2023-06-26 16:09:36889browse

As modern computer systems become increasingly complex and large, concurrency performance has become a necessary tool to solve practical problems. Traditional synchronous programming methods can no longer meet the needs of complex systems. Asynchronous programming has become an important tool for modern programmers to develop high-performance programs. CompletableFuture introduced in Java 8 is a powerful mechanism for asynchronous programming, which can greatly simplify the complexity of asynchronous programming and improve the readability and maintainability of the code. This article will detail the basic concepts of CompletableFuture, building and using asynchronous tasks, and how to handle the results of asynchronous tasks.

CompletableFuture Overview

CompletableFuture is a class that implements the Future interface. It is a new asynchronous programming tool provided by Java 8 for expressing asynchronous operations and processing operation results. Different from the Future interface, CompletableFuture provides more powerful tools to better express the results of asynchronous operations. The CompletableFuture class supports chaining multiple asynchronous operations to form a streaming asynchronous operation chain, similar to Observable in the RxJava framework and AsyncTask in Android.

With CompletableFuture, developers can easily build asynchronous programming logic without having to consider a lot of threading and locking details. The use of CompletableFuture is also very simple and clear. They change the way asynchronous programming is implemented, reduce the defects of callback-based asynchronous programming, and improve code readability and maintainability.

Basic usage

The basic usage of CompletableFuture is to build an asynchronous operation chain. You can use the thenApplyAsync, thenComposeAsync, thenCombineAsync and thenAcceptAsync methods to link asynchronous operations together. The thenApplyAsync method is used to apply a functor (function) to another asynchronous result to create a new asynchronous task; the thenComposeAsync method is used to map and link the result of an asynchronous operation to another asynchronous task; the thenCombineAsync method is used to Combine the results of two asynchronous operations and create a new asynchronous operation; the thenAcceptAsync method is used to consume an asynchronous result.

The following is a simple example showing the basic asynchronous programming pattern:

// 异步执行任务1
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");

// 异步执行任务2,并在任务1完成之后执行
CompletableFuture<String> future2 = future1.thenApplyAsync(result -> result + " World");

// 等待任务2执行完成,并处理结果
future2.thenAcceptAsync(result -> System.out.println(result));

This code shows how to use CompletableFuture to build a simple and powerful asynchronous programming model to form an asynchronous operation chain . First, use the supplyAsync method to execute task 1 asynchronously. This method will convert a synchronous task into an asynchronous task. Then use the thenApplyAsync method to concatenate the result of task 1 ("Hello") with the "World" string and build a new string object that represents a map of the results. Finally, use the thenAcceptAsync method to process the result and print it. This example is very simple, but it demonstrates the basic features of CompletableFuture, especially the capabilities of chain programming and asynchronous programming.

Three states of asynchronous operations

CompletableFuture has three states, which are:

  • Uncompleted (Uncompleted): CompletableFuture is not available yet Set relevant results. For example, the asynchronous task has not started running, the asynchronous task is in progress, or the asynchronous task has run but not completed.
  • Completed Exceptionally: CompletableFuture encountered an exception during runtime, resulting in the operation not being completed. The type of exception is determined by the Exception type set by calling the completeExceptionally method.
  • Completed (Completed Normally) : CompletableFuture has been completed and the result has been returned successfully. The type of the result is determined by the parameter type passed by calling the complete or completeAsync method.

Any CompletableFuture object has only one completion or exception state, and will transition from the uncompleted state to a final state. You can use the isDone method to check whether a CompletableFuture has completed. For example: future.isDone().

Explore CompletableFuture's methods further

CompletableFuture provides many methods to delay the execution of an asynchronous task and process its results. Here are some of the main CompletableFuture methods:

  • Runnable 包装器:runAsync 和 supplyAsync 是 CompletableFuture 运行异步任务的最简单的方式。
  • 转换函数:我们可以通过使用 thenApply 方法来将一个异步操作的结果转化为另一个异步操作的参数。这也被称为异步映射。同样,使用 thenAccept 方法将一个异步结果作为消耗者。
  • Bi Function:thenCombine 方法将两个 CompletableFuture 对象组合在一起,同时为它们提供一个组合函数。
  • 异常处理:当 Future 对象抛出异常时,我们可以使用 exceptionally 方法指定如何处理异常。另外,使用 handle 方法还可以处理正常的结果和异常的情况。
  • 组合多个结果:使用 allOf 和 anyOf 方法处理多个异步操作的结果。其中 allOf 则等待所有异步操作完成,而 anyOf 仅需等待其中任意一个异步操作完成。

案例演示

我们来看一个更加复杂的例子,该例子将涉及到 CompletableFuture 的多种使用模式:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureDemo {

   public static void main(String args[]) throws InterruptedException, ExecutionException {

      // 创建异步任务1
      CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 2 + 3);

      // 创建异步任务2
      CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 3 * 4);

      // 组合异步任务1和异步任务2,使用BiFunction对象作为组合函数
      CompletableFuture<Integer> future3 = future1.thenCombineAsync(future2, (result1, result2) -> result1 * result2);

      // 创建异步任务3
      CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> 2 + 7);

      // 组合异步任务1和异步任务3,使用Function类型的函数
      CompletableFuture<Integer> future5 = future1.thenComposeAsync(result -> CompletableFuture.supplyAsync(() -> result + 5));

      // 组合异步任务1、异步任务2和异步任务3,使用组合函数,返回类型为Void
      CompletableFuture<Void> future6 = CompletableFuture.allOf(future1, future2, future4).thenAcceptAsync((Void) -> {
         try {
            System.out.println("The result of future1 is: " + future1.get());
            System.out.println("The result of future2 is: " + future2.get());
            System.out.println("The result of future4 is: " + future4.get());
         } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
         }
      });

      // 等待所有异步任务执行完毕
      CompletableFuture.allOf(future3, future5, future6).join();
   }
}

这段代码展示了 CompletableFutures 几种常用方法:suplyAsync、thenCombineAsync、thenComposeAsync和acceptAsync、allOf、isDone、join、get 和其他一些方法。我们首先定义了三个不同的 CompletableFuture 对象,根据不同的函数来完成,然后使用 thenCombineAsync 方法将这两个对象组合成一个对象。我们还使用 thenComposeAsync 构建了另一个异步结果,从这两个对象中获取了一些信息。最后,我们使用 allOf 方法来组合三个异步事件并在这三个异步操作完成后将它们组合在一个 Void 异步操作中,并使用 thenAcceptAsync 接受它们的值并将其打印到控制台上。

异步编程实践

异步编程是一项复杂的任务,有很多复杂性,需要更多的时间和经验来正确地完成。我们需要明确异步编程的目的,并准确掌握 CompletableFuture 机制,才能写出简洁、精简、易维护的代码。

异步编程的另一个好处是提高应用程序的性能和吞吐量,因为我们可以为多个 CPU 核心优化和并发运行任务。然而,它也有一定的成本,包括更复杂的代码、需要加锁的数据结构和其他潜在的性能问题。但是,使用 CompletableFuture 进行异步编程,可以使代码更具可读性和可维护性,并减少程序员编写出还原异步操作的代码的负担。异步编程虽然存在挑战,但对于开发高性能应用程序至关重要。

结论

这篇文章介绍了 CompletableFuture 和其在 Java 异步编程中的应用。CompletableFuture 类是一种强大的异步编程工具,可以帮助开发人员优雅地解决异步问题。虽然异步编程有一定的复杂性,但是通过理解 CompletableFuture 的基础和高级特性,我们可以优化代码并提高我们应用程序的性能。

总结起来,CompletableFuture 是 Java 8 提供的一种强大的异步编程工具,可用于解决异步操作的问题。CompletableFuture 可以通过链式编程来组成异步操作链,在提高效率的同时也为程序提供了更加优雅的代码实现方案。尽管异步编程带来了一些复杂性,需要开发人员在编写代码时更加小心,但当正确地使用 CompletableFuture 时,它可以帮助我们轻松地实现高效率、可维护和高质量的代码。

The above is the detailed content of How to use CompletableFuture function in Java for asynchronous programming. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn