在我们的日常开发中我们会经常用到异步代码来提升我们api的性能,也有这样的场景,比如我们在A异步操作后,取得A的结果后,又需要进行B操作。借助java8的CompletableFuture,代码如下
public class Java8Test {
public static void main(String[] args){
CompletableFuture firstFuture = CompletableFuture.supplyAsync(()->{
System.out.println("start to execute supplyAsync");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end to execute supplyAsync");
return "firstFuture";
}).thenAccept(otxGroupData -> {
System.out.println("start to execute thenAccept");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end to execute thenAccept");
}).exceptionally((e) -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e.printStackTrace();
}
return null;
});
System.out.println("main end");
}
}
可以看到程序会先执行supplyAsync,再执行thenAccept,这样会有一个疑问,如果还没执行完thenAccept,主线程这是执行完退出了,会影响到我们的thenAccept执行吗?先看运行结果:
可以看到主线程执行完提出了,并没有等待thenAccept的执行。这是我们可以在主线程加上firstFuture.get();这句代码,get()会阻塞在这儿等待整个firstFuture的流程都执行完成,然后才回到主线程执行。
public class Java8Test {
public static void main(String[] args){
CompletableFuture firstFuture = CompletableFuture.supplyAsync(()->{
System.out.println("start to execute supplyAsync");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end to execute supplyAsync");
return "firstFuture";
}).thenAccept(otxGroupData -> {
System.out.println("start to execute thenAccept");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end to execute thenAccept");
}).exceptionally((e) -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e.printStackTrace();
}
return null;
});
try {
firstFuture.get();
System.out.println("main end");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
运行结果:
这样就不用担心thenAccept执行不到了。CompletableFuture的异步的功能还很强大,自己也在学习中,后面再来总结,未完待续。