CompletableFuture是Future接口的扩展和增强。CompletableFuture实现了Future接口,并在此基础上进行了丰富地扩展,完美地弥补了Future上述的种种问题。更为重要的是,CompletableFuture实现了对任务的编排能力。借助这项能力,我们可以轻松地组织不同任务的运行顺序、规则以及方式。
运用:
kotlin
public class CompletableFutureHandle {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发生异常");
// throw new RuntimeException("我是异常..");
});
future.handle(new BiFunction<Void, Throwable, Object>() {
@Override
public Object apply(Void unused, Throwable throwable) {
if (null == throwable) {
System.out.println("没有发生异常.");
}else {
System.out.println("发生了异常.");
}
return null;
}
});
System.out.println(future.get());
}
}
执行结果:


根据的结果是否抛出异常回调不同的方法.两种处理合并在了一个方法中.
runAsync方法:
可以参考前面的文章.
handle方法:
typescript
public <U> CompletableFuture<U> handle(
BiFunction<? super T, Throwable, ? extends U> fn) {
return uniHandleStage(null, fn);
}
函数式接口BiFunction:
typescript
@FunctionalInterface
public interface BiFunction<T, U, R> {
/**
* Applies this function to the given arguments.
*
* @param t the first function argument
* @param u the second function argument
* @return the function result
*/
R apply(T t, U u);
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of output of the {@code after} function, and of the
* composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then
* applies the {@code after} function
* @throws NullPointerException if after is null
*/
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
函数式接口BiFunction理解:
1.apply方法就是接收两个泛型参数,然后由子类实现.
2.andThen方法.提供了默认实现.接收一个Function的实现对象,然后调用他的方法.
uniHandleStage方法:
typescript
private <V> CompletableFuture<V> uniHandleStage(
Executor e, BiFunction<? super T, Throwable, ? extends V> f) {
if (f == null) throw new NullPointerException();
CompletableFuture<V> d = new CompletableFuture<V>();
if (e != null || !d.uniHandle(this, f, null)) {
UniHandle<T,V> c = new UniHandle<T,V>(e, d, this, f);
push(c);
c.tryFire(SYNC);
}
return d;
}
uniHandleStage方法理解:

其余的像push方法 tryFire方法可以参考前面的文章.
uniHandle方法:
ini
final <S> boolean uniHandle(CompletableFuture<S> a,
BiFunction<? super S, Throwable, ? extends T> f,
UniHandle<S,T> c) {
Object r; S s; Throwable x;
if (a == null || (r = a.result) == null || f == null)
return false;
if (result == null) {
try {
if (c != null && !c.claim())
return false;
if (r instanceof AltResult) {
x = ((AltResult)r).ex;
s = null;
} else {
x = null;
@SuppressWarnings("unchecked") S ss = (S) r;
s = ss;
}
completeValue(f.apply(s, x));
} catch (Throwable ex) {
completeThrowable(ex);
}
}
return true;
}
uniHandle方法理解:

get方法可以参考前面文章.
链式运用:
csharp
public class completableFutures_supplyAsync {
public static void main(String[] args) throws InterruptedException {
CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("返回a");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "a";
}).applyToEitherAsync(CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("返回b");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "b";
}), res -> res).whenCompleteAsync((res, err) -> System.out.println("最快返回:" + res));
TimeUnit.SECONDS.sleep(10);
}
}
执行结果:

supplyAsync方法:
可以参考前面有返回值的异步操作.
applyToEitherAsync方法:
typescript
public <U> CompletableFuture<U> applyToEitherAsync(
CompletionStage<? extends T> other, Function<? super T, U> fn) {
return orApplyStage(asyncPool, other, fn);
}
applyToEitherAsync方法理解:


函数接口前面有讲解.
orApplyStage方法:
typescript
private <U extends T,V> CompletableFuture<V> orApplyStage(
Executor e, CompletionStage<U> o,
Function<? super T, ? extends V> f) {
CompletableFuture<U> b;
if (f == null || (b = o.toCompletableFuture()) == null)
throw new NullPointerException();
CompletableFuture<V> d = new CompletableFuture<V>();
if (e != null || !d.orApply(this, b, f, null)) {
OrApply<T,U,V> c = new OrApply<T,U,V>(e, d, this, b, f);
orpush(b, c);
c.tryFire(SYNC);
}
return d;
}
orApplyStage方法理解:

orApply方法:
typescript
final <R,S extends R> boolean orApply(CompletableFuture<R> a,
CompletableFuture<S> b,
Function<? super R, ? extends T> f,
OrApply<R,S,T> c) {
Object r; Throwable x;
if (a == null || b == null ||
((r = a.result) == null && (r = b.result) == null) || f == null)
return false;
tryComplete: if (result == null) {
try {
if (c != null && !c.claim())
return false;
if (r instanceof AltResult) {
if ((x = ((AltResult)r).ex) != null) {
completeThrowable(x, r);
break tryComplete;
}
r = null;
}
@SuppressWarnings("unchecked") R rr = (R) r;
completeValue(f.apply(rr));
} catch (Throwable ex) {
completeThrowable(ex);
}
}
return true;
}
orApply方法理解:

关于跳转可以了解一下下面这个demo.跑一下结果就理解了.
ini
public class JumpToTest {
public static void main(String[] args) {
label1:
for (int i = 1; i <=5; i++) {
for (int j = 1; j <= 10; j++) {
if (j == 5)
break label1;
System.out.print(j+" ");
}
}
//结果 1 2 3 4
System.out.println();
System.out.println("*******************");
label2:
for (int i = 1; i <=5; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 2)
continue label2;
System.out.print(j+" ");
}
}
//结果 1 1 1 1 1
System.out.println();
System.out.println("*******************");
for (int i = 1; i <=5; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 2)
continue;
System.out.print(j+" ");
}
}
System.out.println();
System.out.println("*******************");
//结果 1 3 4 5 1 3 4 5 1 3 4 5 1 3 4 5 1 3 4 5
for (int i = 1; i <=5; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 2)
break;
System.out.print(j+" ");
}
}
//结果 1 1 1 1 1
}
}

whenCompleteAsync方法:
swift
public CompletableFuture<T> whenCompleteAsync(
BiConsumer<? super T, ? super Throwable> action) {
return uniWhenCompleteStage(asyncPool, action);
}
函数式接口BiConsumer:
java
/**
* Represents an operation that accepts two input arguments and returns no
* result. This is the two-arity specialization of {@link Consumer}.
* Unlike most other functional interfaces, {@code BiConsumer} is expected
* to operate via side-effects.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #accept(Object, Object)}.
*
* @param <T> the type of the first argument to the operation
* @param <U> the type of the second argument to the operation
*
* @see Consumer
* @since 1.8
*/
@FunctionalInterface
public interface BiConsumer<T, U> {
/**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
*/
void accept(T t, U u);
/**
* Returns a composed {@code BiConsumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code BiConsumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
Objects.requireNonNull(after);
return (l, r) -> {
accept(l, r);
after.accept(l, r);
};
}
}
函数式接口BiConsumer理解:
1.accept函数就是接收两个参数,然后执行我们实现的任务.
2.执行完accept方法以后,在链式调用传入的accept方法.
uniWhenCompleteStage方法:
typescript
private CompletableFuture<T> uniWhenCompleteStage(
Executor e, BiConsumer<? super T, ? super Throwable> f) {
if (f == null) throw new NullPointerException();
CompletableFuture<T> d = new CompletableFuture<T>();
if (e != null || !d.uniWhenComplete(this, f, null)) {
UniWhenComplete<T> c = new UniWhenComplete<T>(e, d, this, f);
push(c);
c.tryFire(SYNC);
}
return d;
}
uniWhenCompleteStage方法理解:

uniWhenComplete方法:
ini
final boolean uniWhenComplete(CompletableFuture<T> a,
BiConsumer<? super T,? super Throwable> f,
UniWhenComplete<T> c) {
Object r; T t; Throwable x = null;
if (a == null || (r = a.result) == null || f == null)
return false;
if (result == null) {
try {
if (c != null && !c.claim())
return false;
if (r instanceof AltResult) {
x = ((AltResult)r).ex;
t = null;
} else {
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
f.accept(t, x);
if (x == null) {
internalComplete(r);
return true;
}
} catch (Throwable ex) {
if (x == null)
x = ex;
}
completeThrowable(x, r);
}
return true;
}
uniWhenComplete方法理解:

get方法可以参考前面的文章.如果有哪里不明了,可以从第一篇文章看起.好多盲点会清晰很多.
语雀地址www.yuque.com/itbosunmian...?
《Go.》 密码:xbkk 欢迎大家访问.提意见.
无言独上西楼,月如钩,寂寞梧桐深院锁清秋,剪不断,理还乱,别是一番滋味在心头.