一、Promise的概念
Promise就是一种对异步操作结果的规范,类似于“保证书”,保证异步操作在未来一定会有一个返回值或异常抛出。
常见的Promise的状态有三种:Pending(进行中)、Resolved(已成功完成)、Rejected(已失败)。
public interface Promise extends Future {
<U> Promise thenApply(Function<? super V, ? extends U> fn);
<U> Promise<U> thenCompose(Function<? super V, ? extends CompletionStage<? extends U>> fn);
Promise<V> exceptionally(Function<Throwable, ? extends V> fn);
Promise<V> whenComplete(BiConsumer<? super V, ? super Throwable> action);
Promise<V> whenCompleteAsync(BiConsumer<? super V, ? super Throwable> action);
}
JavaPromise就是在java.util.concurrent.Future的基础上分析封装出来的Promise实现。
下面我们就从不同的角度来深入了解JavaPromise的相关知识。
二、使用JavaPromise实现异步任务
在多线程编程中,异步任务非常常见,可以通过JavaPromise轻松实现异步任务操作。
例如下面的代码:我们创建一个简单的异步任务,该任务在1秒钟后会返回一个结果。
Promise<String> promise = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "异步任务已完成";
});
注意:以上代码中的supplyAsync方法创建了异步任务供后续调用使用。
三、JavaPromise中的thenApply方法
JavaPromise的thenApply方法可以将一个Promise实例转换成另一个Promise实例,并可以在转换的同时对得到的结果进行一些处理。
例如下面的代码:我们创建一个简单的异步任务,该任务在1秒钟后会返回一个结果。利用thenApply方法我们可以对结果进行处理。
Promise<String> promise = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "a";
})
.thenApply(s -> s + "b")
.thenApply(s -> s + "c");
通过thenApply方法,我们可以将获取的结果转为另一个Promise,并对其进行处理。
四、JavaPromise中的thenCompose方法
thenCompose方法也是将一个Promise实例转换成另一个Promise实例,不同的是转换后的Promise是一个嵌套的Promise,可以一步步的对多个Promise进行处理。
例如下面的代码:我们创建了两个简单的异步任务,第二个任务需要第一个任务的结果作为输入。因此我们需要以thenCompose的形式,嵌套执行两个异步任务。
Promise<String> promise = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "a";
})
.thenCompose(s -> CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return s + "b";
}));
注意:以上代码中第二个异步任务需要调用第一个任务的结果作为输入。
五、JavaPromise中的exceptionally方法
exceptionally方法用于在异步任务执行过程中现有异常,或任务失败时,提供一个备用值或者执行回调函数。
例如下面的代码:我们创建了一个简单的异步任务,该任务会随机抛出异常。为了避免程序抛出异常后无法继续执行下去,我们使用exceptionally方法对异常进行处理,并在处理时提供一个备用值。
Promise<String> promise = CompletableFuture.supplyAsync(() -> {
Random random = new Random();
if (random.nextBoolean()) {
throw new RuntimeException("随机异常");
}
return "正常执行完成";
})
.exceptionally(ex -> "备用值");
在以上代码中,发生异常时,exceptionally方法会提供一个备用值。
六、JavaPromise中的whenComplete方法
whenComplete方法与exceptionally方法类似,也是当异步任务执行过程中发生异常时提供一个备用值或者执行回调函数的方法。
不同的是,whenComplete方法无论任务是否执行成功或失败都会得到执行。而且还可以在执行回调函数时继续对Future的操作。
例如下面的代码:我们创建一个简单的异步任务,当任务在1秒钟后完成时,根据随机值抛出异常。在异常发生时,我们将对异常进行处理,并继续异步操作。
Promise<String> promise = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
Random random = new Random();
if (random.nextBoolean()) {
throw new RuntimeException("随机异常");
}
return "正常执行完成";
})
.whenComplete((s, ex) -> {
if (ex != null) {
System.out.println("发生了异常:" + ex.getMessage());
}
System.out.println("异步任务已完成:" + s);
});
七、JavaPromise中的whenCompleteAsync方法
whenCompleteAsync方法与whenComplete方法类似,也是当异步任务执行过程中发生异常时提供一个备用值或者执行回调函数的方法。
不同的是,whenCompleteAsync方法提供了异步执行回调函数的方式。
例如下面的代码:我们创建一个简单的异步任务,在1秒钟后随机抛出异常。在异常发生时,我们将对异常进行处理,并在回调处理中进行日志记录。并且在处理日志时,我们使用了whenCompleteAsync方法进行异步日志记录操作。
Executors.newSingleThreadExecutor().submit(() -> {
Promise<String> promise = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
Random random = new Random();
if (random.nextBoolean()) {
throw new RuntimeException("随机异常");
}
return "正常执行完成";
});
promise.whenCompleteAsync((s, ex) -> {
if (ex != null) {
System.out.println("发生了异常:" + ex.getMessage());
}
Executors.newSingleThreadExecutor().submit(() -> {
System.out.println("日志输出:" + System.currentTimeMillis());
});
});
});
在该代码中,我们将日志记录异步操作通过whenCompleteAsync方法进行了处理。
以上就是对JavaPromise的介绍,通过以上几点我们可以看出,JavaPromise是Java8中新增的异步编程技术,它可以轻松实现异步操作,并提供了灵活的异步操作方式与回调处理机制。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/286706.html