使用场景:一个接口需要查询五部分数据,a,b,c三部分数据直接没有关系,可以并行查询,但是,d,e数据需要等a数据查询结果返回才可以查询,如果使用普通的FutureTask可以实现,但是在项目中,我们不是直接new Thread的,需要使用线程池,所以 CompletableFuture,既可以异步编排,又可以使用线程池执行.
启动异步任务 runAsync supplyAsync
package com.buba.springbootdemo.thread;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*
*/
public class Demo {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
/**
* 异步执行,无返回值
* public static CompletableFuture<Void> runAsync(Runnable runnable)
* public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)
*/
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("线程执行"), executor);
/**
* 有返回值
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
*/
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 1, executor);
//返回1
System.out.println(future2.get());
}
}
完成回调与异常感知 whenComplete exceptionally
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
/**
* whenComplete当前面的线程执行完后执行的操作,没有async的方法表示跟前面的线程用同一个线程执行,加async的方法表示使用新的线程执行
* exceptionally,表示如果出现异常的话执行的方法,没有异常不会执行,并且它可以修改返回值,而whenComplete不可以修改返回值
*
* public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
* public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)
* public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)
*
* 返回的结果:null,异常信息:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
* java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
* 10
*/
CompletableFuture<Integer> future1 = CompletableFuture
.supplyAsync(() -> 1/0, executor)
.whenCompleteAsync((result,exception)-> System.out.println("返回的结果:"+result+",异常信息:"+exception),executor)
.exceptionally((ex)->{
System.out.println(ex);
return 10;
});
System.out.println(future1.get());
}
完成回调与异常感知 handle
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
/**
*
* handle方法跟whenComplete一样都是当之前的线程执行完再执行,但是它可以修改返回的结果
*
* public <U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)
* public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
* public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
*
* 返回结果:1,异常信息:null
* 2
*/
CompletableFuture<Integer> future2 = CompletableFuture
.supplyAsync(() -> 1, executor)
.handleAsync((result,exception)->{
System.out.println("返回结果:"+result+",异常信息:"+exception);
return 2;
},executor);
System.out.println(future2.get());
}
线程串行化 thenRun,thenAccept,thenApply
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
/**
* thenRun等之前线程执行完再执行,获取不到之前线程返回结果,自己当前线程也没有返回结果
* public CompletableFuture<Void> thenRun(Runnable action)
* public CompletableFuture<Void> thenRunAsync(Runnable action)
* public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor)
*/
CompletableFuture<Void> future1 = CompletableFuture
.supplyAsync(() -> 1, executor)
.thenRunAsync(() -> System.out.println("后续线程执行"), executor);
/**
* thenAccept等之前线程执行完再执行,能获取到之前线程返回结果,自己当前线程没有返回结果
* public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
* public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
* public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor)
*/
CompletableFuture<Void> future2 = CompletableFuture
.supplyAsync(() -> 1, executor)
.thenAcceptAsync((result) -> System.out.println("后续线程执行,前面线程执行结果:" + result), executor);
/**
* thenApply等之前线程执行完再执行,能获取到之前线程返回结果,自己当前线程有返回结果
* public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
* public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
* public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
*/
CompletableFuture<Integer> future3 = CompletableFuture
.supplyAsync(() -> 1, executor)
.thenApplyAsync((result) -> {
System.out.println("后续线程执行,前面线程执行结果:" + result);
return 2;
}, executor);
System.out.println(future3.get());
/**
* 后续线程执行
* 后续线程执行,前面线程执行结果:1
* 后续线程执行,前面线程执行结果:1
* 2
*/
}
两任务组合-都要完成 thenCombineAsync ,runAfterBothAsync ,thenAcceptBothAsync
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
CompletableFuture future1 = CompletableFuture
.supplyAsync(() -> {
System.out.println("第一个线程执行完了");
return 1;
}, executor);
/**
*
* runAfterBoth等前面两个线程都执行完,再执行的操作,获取不到前面的返回结果,但自己无返回结果
* thenAcceptBoth等前面两个线程都执行完,再执行的操作,可以获取到前面的返回结果,但自己无返回结果
* thenCombine等前面两个线程都执行完,再执行的操作,可以获取到前面的返回结果,自己有返回结果
*/
CompletableFuture
.runAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("第二个线程执行完了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, executor)
.runAfterBothAsync(future1, () -> System.out.println("前面两个都执行完了执行的"), executor);
CompletableFuture
.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("第二个线程执行完了");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
}, executor)
.thenAcceptBothAsync(future1, (result1,result2) -> System.out.println("前面两个都执行完了执行的,返回结果1:"+result1+",返回结果2:"+result2), executor);
CompletableFuture future3 = CompletableFuture
.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("第二个线程执行完了");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
}, executor)
.thenCombineAsync(future1, (result1, result2) -> {
System.out.println("前面两个都执行完了执行的,返回结果1:" + result1 + ",返回结果2:" + result2);
return 3;
}, executor);
System.out.println(future3.get());
}
两任务组合有一个完成 runAfterEitherAsync,acceptEitherAsync,applyToEitherAsync
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
CompletableFuture future1 = CompletableFuture
.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第一个线程执行完了");
return 1;
}, executor);
/**
*
* runAfterEitherAsync等前面两个线程中其中一个执行完,再执行的操作,获取不到前面的返回结果,但自己无返回结果
* acceptEitherAsync等前面两个线程中其中一个执行完,再执行的操作,可以获取到前面的返回结果,但自己无返回结果
* applyToEitherAsync等前面两个线程中其中一个执行完,再执行的操作,可以获取到前面的返回结果,自己有返回结果
*/
CompletableFuture
.runAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("第二个线程执行完了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, executor)
.runAfterEitherAsync(future1, () -> System.out.println("前面两个都执行完了执行的"), executor);
CompletableFuture
.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("第二个线程执行完了");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
}, executor)
.acceptEitherAsync(future1, (result1) -> System.out.println("前面两个都执行完了执行的,返回结果1:"+result1), executor);
CompletableFuture future3 = CompletableFuture
.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("第二个线程执行完了");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
}, executor)
.applyToEitherAsync(future1, (result1) -> {
System.out.println("前面两个都执行完了执行的,返回结果1:" + result1);
return 3;
}, executor);
System.out.println(future3.get());
}
多任务组合 allOf,anyOf
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("线程1执行");
return "线程1";
}, executor);
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("线程2执行");
return "线程2";
}, executor);
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
System.out.println("线程3执行");
return "线程3";
}, executor);
/**
* allOf等待所有的Future执行完毕
* anyOf有一个执行完毕就会接着往下走
*/
CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
//得调用get方法进行阻塞
allOf.get();
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2, future3);
System.out.println(anyOf.get());
}