CompletableFuture是Future接口的扩展和增强。CompletableFuture实现了Future接口,并在此基础上进行了丰富地扩展,完美地弥补了Future上述的种种问题。更为重要的是,CompletableFuture实现了对任务的编排能力。借助这项能力,我们可以轻松地组织不同任务的运行顺序、规则以及方式。
运用:
public class CompletableFutureTest2 {
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.whenComplete(new BiConsumer<Void, Throwable>() {
@Override
public void accept(Void unused, Throwable throwable) {
System.out.println("执行完成.");
}
});
//抛出异常回调钩子.
future.exceptionally(new Function<Throwable, Void>() {
@Override
public Void apply(Throwable throwable) {
System.out.println("执行失败"+throwable.getMessage());
return null;
}
});
//异步获取结果.
System.out.println(future.get());
}
}
执行结果:
可以从执行结果看出来,执行完成和抛出异常都调用了回调.
runAsync方法:
可以参考上一篇文章.
whenComplete方法:
public CompletableFuture<T> whenComplete(
BiConsumer<? super T, ? super Throwable> action) {
return uniWhenCompleteStage(null, action);
}
1.函数式接口BiConsumer:
@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);
};
}
}
2.函数式接口BiConsumer方法解释:
accept可以接受两个参数.
有一个默认的实现,接受一个实现了BiConsumer接口的对象达到链式调用.
3.uniWhenCompleteStage方法:
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;
}
4.uniWhenCompleteStage方法解释:
5.uniWhenComplete方法:
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;
}
6.uniWhenComplete方法理解:
7.claim方法:
/**
* Returns true if action can be run. Call only when known to
* be triggerable. Uses FJ tag bit to ensure that only one
* thread claims ownership. If async, starts as task -- a
* later call to tryFire will run action.
*/
final boolean claim() {
Executor e = executor;
if (compareAndSetForkJoinTaskTag((short)0, (short)1)) {
if (e == null)
return true;
executor = null; // disable
e.execute(this);
}
return false;
}
8.claim方法理解:
因为这个方法这个参数传进来的为空,所以不会走到这里.
9.UniWhenComplete构造方法:
UniWhenComplete(Executor executor, CompletableFuture<T> dep,
CompletableFuture<T> src,
BiConsumer<? super T, ? super Throwable> fn) {
super(executor, dep, src); this.fn = fn;
}
10.UniWhenComplete构造方法理解:
把需要执行的任务和CompletableFuture封装到了一起.
11.push方法:
/** Pushes the given completion (if it exists) unless done. */
final void push(UniCompletion<?,?> c) {
if (c != null) {
while (result == null && !tryPushStack(c))
lazySetNext(c, null); // clear on failure
}
}
12.push方法理解:
13.tryPushStack方法:
/** Returns true if successfully pushed c onto stack. */
final boolean tryPushStack(Completion c) {
Completion h = stack;
lazySetNext(c, h);
return UNSAFE.compareAndSwapObject(this, STACK, h, c);
}
14.tryPushStack方法理解:
15.tryFire方法:
final CompletableFuture<T> tryFire(int mode) {
CompletableFuture<T> d; CompletableFuture<T> a;
if ((d = dep) == null ||
!d.uniWhenComplete(a = src, fn, mode > 0 ? null : this))
return null;
dep = null; src = null; fn = null;
return d.postFire(a, mode);
}
16.tryFire方法理解:
里面和上面的方法一样,如果第一阶段任务还是没有结束,返回为空.
17.postFire方法:
/**
* Post-processing by dependent after successful UniCompletion
* tryFire. Tries to clean stack of source a, and then either runs
* postComplete or returns this to caller, depending on mode.
*/
final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
if (a != null && a.stack != null) {
if (mode < 0 || a.result == null)
a.cleanStack();
else
a.postComplete();
}
if (result != null && stack != null) {
if (mode < 0)
return this;
else
postComplete();
}
return null;
}
18.postFire方法理解:
最后还是进行寻找这个任务,是否有下一个任务.进行递归.
exceptionally方法:
/**
* Returns a new CompletableFuture that is completed when this
* CompletableFuture completes, with the result of the given
* function of the exception triggering this CompletableFuture's
* completion when it completes exceptionally; otherwise, if this
* CompletableFuture completes normally, then the returned
* CompletableFuture also completes normally with the same value.
* Note: More flexible versions of this functionality are
* available using methods {@code whenComplete} and {@code handle}.
*
* @param fn the function to use to compute the value of the
* returned CompletableFuture if this CompletableFuture completed
* exceptionally
* @return the new CompletableFuture
*/
public CompletableFuture<T> exceptionally(
Function<Throwable, ? extends T> fn) {
return uniExceptionallyStage(fn);
}
1.函数式接口Function:
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
/**
* Returns a composed function that first applies the {@code before}
* function to its input, and then applies this 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 input to the {@code before} function, and to the
* composed function
* @param before the function to apply before this function is applied
* @return a composed function that first applies the {@code before}
* function and then applies this function
* @throws NullPointerException if before is null
*
* @see #andThen(Function)
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 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
*
* @see #compose(Function)
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @return a function that always returns its input argument
*/
static <T> Function<T, T> identity() {
return t -> t;
}
}
这是一个可以接受一个参数的函数式接口.
2.uniExceptionallyStage方法:
private CompletableFuture<T> uniExceptionallyStage(
Function<Throwable, ? extends T> f) {
if (f == null) throw new NullPointerException();
CompletableFuture<T> d = new CompletableFuture<T>();
if (!d.uniExceptionally(this, f, null)) {
UniExceptionally<T> c = new UniExceptionally<T>(d, this, f);
push(c);
c.tryFire(SYNC);
}
return d;
}
3.uniExceptionallyStage方法理解:
这个方法的逻辑和上面方法逻辑是一样的.
4.uniExceptionally方法:
final boolean uniExceptionally(CompletableFuture<T> a,
Function<? super Throwable, ? extends T> f,
UniExceptionally<T> c) {
Object r; Throwable x;
if (a == null || (r = a.result) == null || f == null)
return false;
if (result == null) {
try {
if (r instanceof AltResult && (x = ((AltResult)r).ex) != null) {
if (c != null && !c.claim())
return false;
completeValue(f.apply(x));
} else
internalComplete(r);
} catch (Throwable ex) {
completeThrowable(ex);
}
}
return true;
}
5.uniExceptionally方法理解:
get方法思路可以参考上一篇文章.
语雀地址www.yuque.com/itbosunmian…?
《Go.》 密码:xbkk 欢迎大家访问.提意见.