利用Java函数进行异步编程:CompletableFuture详解
在Java编程中,异步编程成为了越来越重要的部分。然而,它也成为了越来越复杂的部分。 Java SE 8引进了两个非常强大且相互独立的API,用于完成异步编程:CompletableFuture 和 Reactive Streams。本文将重点介绍CompletableFuture。
CompletableFuture是一个非常强大的类,它提供了大量的方法,用于支持异步编程。它包含了异步操作的方法,并且极易用于链式编程。
Async 和 Sync
首先,我们需要明确异步和同步的区别。同步方法就是在一个线程中执行的方法,它会阻塞线程。异步方法则不会阻塞线程。当异步方法开始执行时,当前线程会继续执行下去。
Java 中异步编程的关键是使用 CompletableFuture 类。
创建CompletableFuture
我们可以通过 CompletableFuture 类来创建新的CompletableFuture 对象,这个对象的初值需要我们来指定。我们可以使用 CompletableFuture 的一些静态工厂方法来创建CompletableFuture 。下面是一个简单的例子:
CompletableFuture<String> future = CompletableFuture.completedFuture("message");
assertTrue(future.isDone());
assertEquals("message", future.getNow(null));
上面例子中,完成的CompletableFuture将被赋值为完成状态。
异步任务
下面,让我们看一下如何在CompletableFuture中执行异步任务。CompletableFuture接收一个执行器作为参数。这个执行器将会在一个新的线程中启动一个任务,而当前线程会继续执行下去。
例如:
public void testSupplyAsync() throws Exception {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
assertEquals("Hello", future.get());
}
上面例子中,supplyAsync() 方法创建一个新的 CompletableFuture 对象,该对象的执行器将在一个新的线程中启动一个带返回值的任务,该任务委托给 supplyAsync() 方法调用的Lambda表达式。
执行多个任务
现在我们知道了如何执行单个异步任务,但是如果我们需要执行多个Async方法,需要让这些方法等待执行完成才能开始下一个方法,这就需要用到串联操作。CompletableFuture 提供了一系列的串联方法,比如 thenAccept()和 thenRun(),同时还有一些与执行器相关的方法,如thenApplyAsync()和thenAcceptAsync()。
例如:
public void testThenAccept() {
StringBuilder sb = new StringBuilder();
CompletableFuture.completedFuture("thenAccept message")
.thenAccept(s -> sb.append(s));
assertTrue(sb.length() > 0);
}
上面例子中,当 CompletableFuture 对象处于完成状态时,thenAccept() 方法就会启动,将异步任务的结果应用于给定的消费者函数。
结论
CompletableFuture 以十分便利的方式支持了 Java 的异步编程。通过工厂方法和各个串联方法,我们可以在 Java 中很方便地处理异步任务。同时CompletableFuture 还支持异常处理和超时控制,使得异步任务处理十分的完整。
CompletableFuture对于处理那些IO密集型的任务以及多线程的任务具有强大的功能,如果我们不知道何种方式实现异步编程,CompletableFuture 是一个不二的选择。
