java.util.concurrent.Future
接口是 Java 并发编程中的一个关键接口,用于表示异步计算的结果。它的主要目的是允许一个线程异步地等待另一个线程的结果。以下是 Future
接口的常见用途和用法:
常见用途:
-
异步任务的提交: 将一个任务提交给
ExecutorService
(线程池)执行,并通过Future
对象来获取任务的执行结果。 -
并发任务的协同: 在多线程环境中,可以使用
Future
对象来协调多个任务的执行,等待其中一个或多个任务完成。 -
延迟任务的处理: 在计划任务执行时,可以使用
ScheduledExecutorService
提交任务,并通过Future
对象来获取任务的执行结果或取消任务。
常见方法:
-
boolean cancel(boolean mayInterruptIfRunning)
: 尝试取消任务的执行。如果任务已经完成,或者由于其他原因无法取消,则返回false
。如果任务正在执行,并且mayInterruptIfRunning
为true
,则会尝试中断任务的执行。 -
boolean isCancelled()
: 如果任务被成功取消,则返回true
。 -
boolean isDone()
: 如果任务已经完成(无论是正常完成、取消还是由于异常),则返回true
。 -
V get()
: 阻塞当前线程,直到任务完成,然后返回任务的结果。如果任务被取消,会抛出CancellationException
。如果任务执行过程中发生异常,会抛出ExecutionException
。 -
V get(long timeout, TimeUnit unit)
: 在指定的时间内等待任务完成。如果在超时前任务完成,返回任务的结果。如果任务被取消,会抛出CancellationException
。如果任务在指定的时间内未完成,会抛出TimeoutException
。
示例用法:
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
// 提交任务并获取 Future 对象
Future<Integer> future = executorService.submit(() -> {
// 模拟耗时操作
Thread.sleep(2000);
return 42;
});
// 主线程继续执行其他操作
System.out.println("Main thread continues its work.");
try {
// 阻塞等待任务完成,并获取结果
Integer result = future.get();
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 关闭线程池
executorService.shutdown();
}
}
在这个示例中,我们使用 ExecutorService
提交一个任务,得到一个 Future
对象。主线程继续执行其他操作,然后通过 future.get()
阻塞等待任务完成,并获取任务的结果。请注意,Future
接口的使用通常与线程池和异步任务相关,能够有效管理多线程环境中的任务执行。
请介绍下java.util.concurrent.CompletableFuture接口常见用途和用法
java.util.concurrent.CompletableFuture
是 Java 8 引入的一个强大的异步编程工具,用于处理异步任务和构建复杂的异步流水线。它扩展了 java.util.concurrent.Future
接口,并提供了更丰富的功能,使得异步编程更加灵活和易于使用。以下是 CompletableFuture
接口的常见用途和用法:
常见用途:
-
异步任务的组合:
CompletableFuture
允许将多个异步任务组合成一个更大的异步任务,以便更好地利用并行性。 -
处理异步任务的结果: 可以使用
thenApply
,thenAccept
,thenCombine
等方法来处理异步任务的结果,进行转换、消费或组合操作。 -
异常处理: 提供了丰富的异常处理方法,如
exceptionally
,handle
,用于处理任务执行过程中可能发生的异常。 -
等待多个任务完成: 使用
CompletableFuture.allOf
或CompletableFuture.anyOf
方法,可以等待多个任务全部完成或任意一个完成。 -
超时处理: 可以使用
completeOnTimeout
方法设置任务的超时,以及orTimeout
方法设置超时后的默认值。 -
构建异步流水线:
thenApply
,thenCompose
,thenCombine
等方法允许构建复杂的异步流水线,串联多个异步操作。
常见方法:
-
static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
: 等待所有给定的CompletableFuture
完成,返回一个新的CompletableFuture
。 -
static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)
: 等待任意给定的CompletableFuture
完成,返回一个新的CompletableFuture
。 -
CompletableFuture<T> thenApply(Function<? super T,? extends U> fn)
: 对CompletableFuture
的结果应用给定的函数,并返回一个新的CompletableFuture
。 -
CompletableFuture<Void> thenAccept(Consumer<? super T> action)
: 在CompletableFuture
的结果上执行给定的操作,返回一个新的CompletableFuture
。 -
CompletableFuture<Void> thenRun(Runnable action)
: 在CompletableFuture
的结果上执行给定的操作,返回一个新的CompletableFuture
。 -
CompletableFuture<U> thenCombine(CompletionStage<? extends V> other, BiFunction<? super T,? super V,? extends U> fn)
: 结合两个CompletableFuture
的结果,并将结果应用给定的函数,返回一个新的CompletableFuture
。 -
CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action)
: 在两个CompletableFuture
都完成后执行给定的操作,返回一个新的CompletableFuture
。 -
CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
: 当CompletableFuture
异常完成时应用给定的函数,返回一个新的CompletableFuture
。
示例用法:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
// 组合两个 CompletableFuture 的结果
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2);
try {
// 等待组合后的 CompletableFuture 完成
String result = combinedFuture.get();
System.out.println(result); // 输出 "Hello World"
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
在这个示例中,我们使用 supplyAsync
方法创建两个异步任务 future1
和 future2
,然后通过 thenCombine
方法组合这两个任务的结果,形成一个新的 CompletableFuture
,最后通过 get
方法等待该组合任务的完成并获取最终的结果。CompletableFuture
还支持更多丰富的操作,如异常处理、流水线操作等,使得异步编程变得更加灵活。
请介绍下CompletionStage接口常见用途和用法
java.util.concurrent.CompletionStage
接口是 Java 并发编程中用于处理异步计算结果的接口。它提供了一组丰富的方法,用于处理异步任务的完成状态、组合多个异步任务的结果以及定义与任务完成相关的操作。以下是 CompletionStage
接口的常见用途和用法:
常见用途:
-
异步任务的组合:
CompletionStage
提供了多个组合方法,如thenApply
,thenAccept
,thenCombine
,允许你在一个或多个异步任务完成时触发后续操作。 -
异常处理: 使用
exceptionally
方法可以指定在任务执行过程中发生异常时要执行的操作,以及使用handle
方法处理异常并返回默认值。 -
等待多个任务完成:
CompletionStage
接口提供了allOf
和anyOf
等方法,用于等待多个任务全部完成或任意一个完成。 -
超时处理: 使用
completeOnTimeout
方法设置任务的超时,以及orTimeout
方法设置超时后的默认值。 -
构建异步流水线: 通过
thenCompose
、thenCombine
等方法,可以构建复杂的异步流水线,串联多个异步操作。 -
任务依赖控制: 使用
thenRun
,thenRunAsync
,thenApplyAsync
等方法,可以在任务完成时触发后续操作,实现任务之间的依赖控制。
常见方法:
-
<U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn)
: 对当前阶段的结果应用给定的函数,并返回一个新的CompletionStage
。 -
CompletionStage<Void> thenAccept(Consumer<? super T> action)
: 在当前阶段的结果上执行给定的操作,返回一个新的CompletionStage
。 -
CompletionStage<Void> thenRun(Runnable action)
: 在当前阶段的结果上执行给定的操作,返回一个新的CompletionStage
。 -
<U,V> CompletionStage<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
: 结合两个阶段的结果,并将结果应用给定的函数,返回一个新的CompletionStage
。 -
CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action)
: 在两个阶段都完成后执行给定的操作,返回一个新的CompletionStage
。 -
CompletionStage<T> exceptionally(Function<Throwable,? extends T> fn)
: 当阶段异常完成时应用给定的函数,返回一个新的CompletionStage
。
示例用法:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public class CompletionStageExample {
public static void main(String[] args) {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
// 组合两个 CompletionStage 的结果
CompletionStage<String> combinedStage = future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2);
// 处理组合后的结果
combinedStage.thenAccept(System.out::println);
// 阻塞等待异步操作完成
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在这个示例中,我们使用 CompletionStage
的 thenCombine
方法组合两个异步任务的结果,然后通过 thenAccept
方法处理组合后的结果。需要注意的是,CompletionStage
接口的操作是异步非阻塞的,因此在处理结果之前,我们通常需要等待异步操作完成,以确保获取到正确的结果。