无返回值调用
import java.util.concurrent.CompletableFuture;
public class TestDemo {
public static void main(String[] args) {
System.out.println("进入主线程=============");
CompletableFuture.runAsync(()->getNum());
System.out.println("主线程结束=============");
}
public void getNum(){
System.out.println("执行线程=============");
}
}
有返回值调用
import java.util.concurrent.CompletableFuture;
public class TestDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 无返回值 runAsync() 有返回值 supplyAsync()
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> getNum());
System.out.println(future.get());
}
private static Integer getNum() {
return 5 / 2;
}
}
使用自定义线程池
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestDemo {
/**
* 自定义线程池
*/
public static ExecutorService service = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 无返回值 runAsync() 有返回值 supplyAsync()
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> getNum(),service);
System.out.println(future.get());
}
private static Integer getNum() {
return 5 / 2;
}
}
处理异常
handleAsync
该方法有两个参数,一种一个是上一步的结果,另一个则是上一步的异常。而且如果出现异常则第一个参数为null,如果没有异常则第二个参数为null。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestDemo {
/**
* 自定义线程池
*/
public static ExecutorService service = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 无返回值 runAsync() 有返回值 supplyAsync()
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> getNum(),service).handleAsync((res, e) -> {
if (res != null) {
return res;
}
if (e != null) {
return 0;
}
return 0;
});
System.out.println(future.get());
}
private static Integer getNum() {
// by zero
return 5 / 0;
}
}
也可以使用 exceptionally
对异常进行单独处理。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestDemo {
/**
* 自定义线程池
*/
public static ExecutorService service = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 无返回值 runAsync() 有返回值 supplyAsync()
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> getNum(),service).exceptionally((e) -> {
System.out.println(e.getMessage());
return 0;
});
System.out.println(future.get());
}
private static Integer getNum() {
// by zero
return 5 / 0;
}
}
多任务组合
使用CompletableFuture主要就是为了完成异步任务的编排。所以第三步也是我们最重要的应用。常见的多个任务组合会有以下几种情况
- 1.业务二会用到业务一的结果
针对第一种情况,这个直接使用上一步handle直接对结果进行处理就好。相对比较简单。
- 2.业务三需要等到业务一和业务二都完成
定义:
业务一 future
业务一 返回值f1
业务二 future2
业务二 返回值f2
如果不需要接收业务一和业务二的返回值,并且自己也不用返回值那么就可以使用:future.runAfterBothAsync(future2,() ->{});
如果需要使用业务一和业务二的返回值,但是在业务三不需要返回值那么可以使用:future.thenAcceptBothAsync(future2,(f1,f2) ->{},service);
如果需要使用业务一和业务二的返回值,并且自己也需要有返回值则使用:future.thenCombineAsync(future2, (f1, f2) -> { return f1 + f2; }, service);
- 3.业务三需要等到业务一或者业务二其中之一完成
定义:
业务一 future
业务一 返回值f1
业务二 future2
业务二 返回值f2
如果不需要接收业务一或者业务二的返回值,并且自己也不用返回值那么就可以使用:future.runAfterEitherAsync(future2,()->{});
如果需要使用业务一或者业务二的返回值,但是在业务三不需要返回值那么可以使用:future.acceptEitherAsync(future2,(f)->{});
如果需要使用业务一或者业务二的返回值,并且自己也需要有返回值则使用:future.applyToEitherAsync(future2,(f)->{return 0;});
具体情况可以根据下面的代码修改测试:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompletableFutureTest {
public static ExecutorService service = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("进入主线程============= ");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
int k = 10 / 2;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("计算结果k = " + k);
return k;
},service);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
int k = 10 * 2;
System.out.println("计算结果k2 = " + k);
return k;
},service);
CompletableFuture<Integer> combineAsync = future.thenCombineAsync(future2, (f1, f2) -> {
System.out.println("最终执行任务3:" + f1 + "===========" + f2);
return f1 + f2;
}, service);
Integer integer = combineAsync.get();
System.out.println("integer = " + integer);
System.out.println("主线程结束============= ");
}
}
标签:异步,Java8,util,future,CompletableFuture,import,返回值,public From: https://www.cnblogs.com/1399z3blog/p/18546195补充:此外还有allOf 和anyOff ,这两个方法可以传入多个任务。同理,allOf是等待所有任务都完成了,anyOf是有任意一个任务完成即可。