java 12.7.1

12.7.1 Completable Futures
When you have a Future object, you need to call get to obtain the value,
blocking until the value is available. The CompletableFuture class
implements the Future interface, and it provides a second mechanism for
obtaining the result. You register a callback that will be invoked (in some
thread) with the result once it is available.
Click here to view code image
CompletableFuture f = . . .;
f.thenAccept(s -> Process the result string s);
In this way, you can process the result without blocking once it is available.
There are a few API methods that return CompletableFuture objects. For
example, you can fetch a web page asynchronously with the experimental
HttpClient class that you will encounter in Chapter 4 of Volume II:
Click here to view code image
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create(urlString))
.GET().build();
CompletableFuture<HttpResponse> f = client.sendAsync(
request, BodyHandler.asString());
It is nice if there is a method that produces a ready-made
CompletableFuture, but most of the time, you need to make your own. To
run a task asynchronously and obtain a CompletableFuture, you don’t
submit it directly to an executor service. Instead, you call the static method
CompletableFuture.supplyAsync. Here is how to read the web page
without the benefit of the HttpClient class:
Click here to view code image
public CompletableFuture readPage(URL url)
{
return CompletableFuture.supplyAsync(() ->
{
try
{
return new String(url.openStream().readAllBytes(), “UTF
-8”);
}
catch (IOException e)
{
throw new UncheckedIOException(e);
}
}, executor);
}
If you omit the executor, the task is run on a default executor (namely the
executor returned by ForkJoinPool.commonPool()). You usually don’t
want to do that.
Caution
Note that the first argument of the supplyAsync method is a
Supplier, not a Callable. Both interfaces describe
functions with no arguments and a return value of type T, but a
Supplier function cannot throw a checked exception. As you can
see from the code above, that was not an inspired choice.
A CompletableFuture can complete in two ways: either with a result, or
with an uncaught exception. In order to handle both cases, use the
whenComplete method. The supplied function is called with the result (or
null if none) and the exception (or null if none).
Click here to view code image
f.whenComplete((s, t) -> {
if (t == null) { Process the result s; }
else { Process the Throwable t; }
});
The CompletableFuture is called completable because you can manually
set a completion value. (In other concurrency libraries, such an object is called
a promise.) Of course, when you create a CompletableFuture with
supplyAsync, the completion value is implicitly set when the task has
finished. But setting the result explicitly gives you additional flexibility. For
example, two tasks can work simultaneously on computing an answer:
Click here to view code image
var f = new CompletableFuture();
executor.execute(() ->
{
int n = workHard(arg);
f.complete(n);
});
executor.execute(() ->
{
int n = workSmart(arg);
f.complete(n);
});
To instead complete a future with an exception, call
Click here to view code image
Throwable t = . . .;
f.completeExceptionally(t);
Note
It is safe to call complete or completeExceptionally on the
same future in multiple threads. If the future is already completed,
these calls have no effect.
The isDone method tells you whether a Future object has been completed
(normally or with an exception). In the preceding example, the workHard and
workSmart methods can use that information to stop working when the result
has been determined by the other method.
Caution
Unlike a plain Future, the computation of a
CompletableFuture is not interrupted when you invoke its
cancel method. Canceling simply sets the Future object to be
completed exceptionally, with a CancellationException. In
general, this makes sense since a CompletableFuture may not
have a single thread that is responsible for its completion. However,
this restriction also applies to CompletableFuture instances
returned by methods such as supplyAsync, which could in principle
be interrupted.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值