前言
当我们的业务变得复杂,需求导致我们需要开多线程去做业务执行,通常我们使用的是Executors去创建+RetreenLock+原子类atomic去操作多个线程间的协作,但当业务更具象化时我们需要对线程存在依赖关系,组合,排序,并发,串行等操作,这时候我们可以用RetreenLock的Condition,用变量来控制unlock去决定是否放开与执行,但终究还是太麻烦,所以今天我整理了CompletableFuture类来操作线程,极大的简化了我们的操作
功能
- 支持supplier(callable)与runnable的组合
- 串行
- 并行
- 多任务组合
- 取消线程任务
- 任务结果获取与动态判断执行顺序
- ..
入门(创建)
/**
* Returns a new CompletableFuture that is asynchronously completed
* by a task running in the {@link ForkJoinPool#commonPool()} with
* the value obtained by calling the given Supplier.
*
* @param supplier a function returning the value to be used
* to complete the returned CompletableFuture
* @param the function's return type
* @return the new CompletableFuture
*/
public static CompletableFuture supplyAsync(Supplier supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* by a task running in the {@link ForkJoinPool#commonPool()} after
* it runs the given action.
*
* @param runnable the action to run before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public static CompletableFuture runAsync(Runnable runnable) {
return asyncRunStage(asyncPool, runnable);
}
使用runnable或supplier来创建异步任务
/**
* 例子
*/
@Test
public void test() {
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
System.out.println("线程A方法执行");
return "线程A方法返回";
});
CompletableFuture.runAsync(() -> {
System.out.println("线程B方法执行");
});
}
串行
串行执行任务,不关心之前任务结果
/**
* Returns a new CompletionStage that, when this stage completes
* normally, executes the given action using this stage's default
* asynchronous execution facility.
*
* See the {@link CompletionStage} documentation for rules
* covering exceptional completion.
*
* @param action the action to perform before completing the
* returned CompletionStage
* @return the new CompletionStage
*/
public CompletionStage thenRunAsync(Runnable action);
/**
* @param :
* @desc : 串行,不关心上一个任务结果(无返回值)
* @dete : 2020/12/29 3:01 下午
* @Return:
* @author: 徐子木
*/
@Test
public void test1() {
CompletableFuture.supplyAsync(() -> {
return "线程A返回";
}).thenRunAsync(() -> {
System.out.println("线程B执行");
});
//线程B执行
}
串行执行任务,依赖上一个任务结果(无返回值)
/**
* Returns a new CompletionStage that, when this stage completes
* normally, is executed using this stage's default asynchronous
* execution facility, with this stage's result as the argument to
* the supplied action.
*
* See the {@link CompletionStage} documentation for rules
* covering exceptional completion.
*
* @param action the action to perform before completing the
* returned CompletionStage
* @return the new CompletionStage
*/
public CompletionStage thenAcceptAsync(Consumer super T> action);
/**
* @param :
* @desc : 串行,依赖上一个任务结果,无返回值
* @dete : 2020/12/29 3:04 下午
* @Return:
* @author: 徐子木
*/
@Test
public void test2() {
CompletableFuture.supplyAsync(() -> {
return "线程A返回结果";
}).thenAcceptAsync(a -> {
System.out.println(a + "/ B线程执行");
});
//线程A返回结果/ B线程执行
串行执行任务,依赖上一个任务结果(有返回值)
/**
* Returns a new CompletableFuture that is asynchronously completed
* by a task running in the {@link ForkJoinPool#commonPool()} with
* the value obtained by calling the given Supplier.
*
* @param supplier a function returning the value to be used
* to complete the returned CompletableFuture
* @param the function's return type
* @return the new CompletableFuture
*/
public static CompletableFuture supplyAsync(Supplier supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
/**
* @param :
* @desc : 串行,依赖上一个任务结果,有返回值
* @dete : 2020/12/29 3:09 下午
* @Return:
* @author: 徐子木
*/
@Test
public void test3() {
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
return "线程A返回结果";
}).thenApplyAsync(a -> {
return a + "/ b方法返回结果";
});
System.out.println(future.join());
//线程A返回结果/ b方法返回结果
}
串行,依赖上一个结果,返回一个常量任务
/**
* Returns a new CompletionStage that, when this stage completes
* normally, is executed using this stage's default asynchronous
* execution facility, with this stage as the argument to the
* supplied function.
*
* See the {@link CompletionStage} documentation for rules
* covering exceptional completion.
*
* @param fn the function returning a new CompletionStage
* @param the type of the returned CompletionStage's result
* @return the CompletionStage
*/
public CompletionStage thenComposeAsync
(Function super T, ? extends CompletionStage> fn);
/**
* @param : thenCompose
* @desc : 串行,依赖上一个结果,返回一个常量任务
* @dete : 2020/12/29 3:14 下午
* @Return: 类似thenApplay, 区别是返回值是completionStage, thenApply返回值是T, 提供该方法为了和其他Future更好的使用
* @author: 徐子木
*/
@Test
public void test4() {
CompletableFuture f = CompletableFuture.completedFuture("常量值A");
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
return "线程A返回结果";
}).thenComposeAsync(a -> {
System.out.println("线程B执行/ " + a);
return f;
});
System.out.println(future.join());
//线程B执行/ 线程A返回结果
//常量值A
}
并行
不依赖前面任务结果,无返回值
/**
* Returns a new CompletionStage that, when this and the other
* given stage complete normally, executes the given action using
* this stage's default asynchronous execution facility.
*
* See the {@link CompletionStage} documentation for rules
* covering exceptional completion.
*
* @param other the other CompletionStage
* @param action the action to perform before completing the
* returned CompletionStage
* @return the new CompletionStage
*/
public CompletionStage runAfterBothAsync(CompletionStage> other,
Runnable action);
/**
* @param :
* @desc : 并行,不依赖前任务结果,无返回值
* @dete : 2020/12/29 3:21 下午
* @Return:
* @author: 徐子木
*/
@Test
public void test5() {
CompletableFuture f = CompletableFuture.completedFuture("常量值A");
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
System.out.println("线程A执行");
return "线程A返回结果";
}).runAfterBothAsync(f, () -> {
System.out.println("线程B执行");
});
//线程B执行
}
并行,多个线程选其最快
/**
* Returns a new CompletionStage that, when either this or the
* other given stage complete normally, executes the given action.
*
* See the {@link CompletionStage} documentation for rules
* covering exceptional completion.
*
* @param other the other CompletionStage
* @param action the action to perform before completing the
* returned CompletionStage
* @return the new CompletionStage
*/
public CompletionStage runAfterEither(CompletionStage> other,
Runnable action);
/**
* @param :
* @desc : 并行, 谁先执行完则会触发下一任务(!二者选其一)
* @dete : 2020/12/29 3:28 下午
* @Return: 无返回值
* @author: 徐子木
*/
@Test
public void test6() {
CompletableFuture futureA = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程A任务执行");
});
CompletableFuture.runAsync(() -> {
System.out.println("线程B任务执行");
}).runAfterEither(futureA, () -> {
System.out.println("最先执行完");
});
//线程B任务执行
//最先执行完
}
并行,多个线程谁执行最快选其一,并执行他
/**
* Returns a new CompletionStage that, when either this or the
* other given stage complete normally, is executed using this
* stage's default asynchronous execution facility, with the
* corresponding result as argument to the supplied action.
*
* See the {@link CompletionStage} documentation for rules
* covering exceptional completion.
*
* @param other the other CompletionStage
* @param action the action to perform before completing the
* returned CompletionStage
* @return the new CompletionStage
*/
public CompletionStage acceptEitherAsync
(CompletionStage extends T> other,
Consumer super T> action);
/**
* @param :
* @desc : 并行,谁执行最快则触发下一任务,并执行他
* @dete : 2020/12/29 3:58 下午
* @Return: 同理applyToEitherAsync 有返回值
* @author: 徐子木
*/
@Test
public void test7() {
CompletableFuture futureA = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "线程A执行结果";
});
CompletableFuture.supplyAsync(() -> {
return "线程B执行结果";
}).acceptEitherAsync(futureA, x -> {
System.out.println(x);
});
//线程B执行结果
}
异常
如果前有任务触发异常,则会拦截到并处理
/**
* 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 exceptionally(
Function fn) {
return uniExceptionallyStage(fn);
}
/**
* @param :
* @desc : 如果之前的任务有异常,则调用exceptionally
* @dete : 2020/12/29 4:04 下午
* @Return: 同理handleAsync 可以处理上一任务的返回值
* @author: 徐子木
*/
@Test
public void test8() {
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
return "线程A执行结果";
}).thenApplyAsync(a -> {
if (true)
throw new RuntimeException("线程B抛出错误");
return "线程B执行结果";
}).exceptionally(e -> {
e.printStackTrace();
return "┭┮﹏┭┮";
});
System.out.println(future.join());
//java.lang.RuntimeException: 线程B抛出错误
Lock lock = new ReentrantLock();
}
任务组合
allOf 所有任务需要执行完毕才会触发下一个任务的执行
/**
* Returns a new CompletableFuture that is completed when all of
* the given CompletableFutures complete. If any of the given
* CompletableFutures complete exceptionally, then the returned
* CompletableFuture also does so, with a CompletionException
* holding this exception as its cause. Otherwise, the results,
* if any, of the given CompletableFutures are not reflected in
* the returned CompletableFuture, but may be obtained by
* inspecting them individually. If no CompletableFutures are
* provided, returns a CompletableFuture completed with the value
* {@code null}.
*
* Among the applications of this method is to await completion
* of a set of independent CompletableFutures before continuing a
* program, as in: {@code CompletableFuture.allOf(c1, c2,
* c3).join();}.
*
* @param cfs the CompletableFutures
* @return a new CompletableFuture that is completed when all of the
* given CompletableFutures complete
* @throws NullPointerException if the array or any of its elements are
* {@code null}
*/
public static CompletableFuture allOf(CompletableFuture>... cfs) {
return andTree(cfs, 0, cfs.length - 1);
}
anyOf 任意一任务执行完毕都会触发下一个任务的执行
/**
* Returns a new CompletableFuture that is completed when any of
* the given CompletableFutures complete, with the same result.
* Otherwise, if it completed exceptionally, the returned
* CompletableFuture also does so, with a CompletionException
* holding this exception as its cause. If no CompletableFutures
* are provided, returns an incomplete CompletableFuture.
*
* @param cfs the CompletableFutures
* @return a new CompletableFuture that is completed with the
* result or exception of any of the given CompletableFutures when
* one completes
* @throws NullPointerException if the array or any of its elements are
* {@code null}
*/
public static CompletableFuture
取消执行线程与其他功能
cancel
/**
* If not already completed, completes this CompletableFuture with
* a {@link CancellationException}. Dependent CompletableFutures
* that have not already completed will also complete
* exceptionally, with a {@link CompletionException} caused by
* this {@code CancellationException}.
*
* @param mayInterruptIfRunning this value has no effect in this
* implementation because interrupts are not used to control
* processing.
*
* @return {@code true} if this task is now cancelled
*/
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = (result == null) &&
internalComplete(new AltResult(new CancellationException()));
postComplete();
return cancelled || isCancelled();
}
是否取消
/**
* Returns {@code true} if this CompletableFuture was cancelled
* before it completed normally.
*
* @return {@code true} if this CompletableFuture was cancelled
* before it completed normally
*/
public boolean isCancelled() {
Object r;
return ((r = result) instanceof AltResult) &&
(((AltResult)r).ex instanceof CancellationException);
}
...
本人选取了一些比较常用的,还有其他不完善的功能大家可以去看源码自行探索
希望能对同学们能有帮助,随手点个赞再走吧,球球了