CompletableFuture类实现了CompletionStage和Future接口。Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种阻塞的方式显然和我们的异步编程的初衷相违背,为了解决这个问题,JDK吸收了guava的设计思想,加入了Future的诸多扩展功能形成了CompletableFuture。
CompletableFutureApi:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html
CompletableFuture的静态方法
首先了解下都有哪些静态方法:
- runAsync(Runnable runnable):该方法返回
CompletableFuture<Void>
public static void main(String[] args) {
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
try {
System.out.println(Thread.currentThread().getName() + ": runAsync=======开始");
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + ": runAsync=======结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("+++++++++++++++++++++++++++++++");
voidCompletableFuture.join();
System.out.println("-------------");
}
需要注意的是使用的默认的线程池ForkJoinPool.commonPool(),待会详细介绍ForkJoinPool.commonPool();里面的线程都是守护线程,Main方法结束,线程也就随着结束了。
- runAsync(Runnable runnable,Executor executor)
executor是我们自定义的线程池。
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
try {
System.out.println(Thread.currentThread().getName() + ": runAsync=======开始");
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + ": runAsync=======结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
},executorService);
System.out.println("+++++++++++++++++++++++++++++++");
executorService.shutdown();
System.out.println("-------------");
}
这样就可以使用自定义的线程池了,使用默认的还是自定义的,这个本人未找到资料证明哪个效率更高。下面介绍方法如果有Executor 参数,均是这样使用,不再累赘。
- supplyAsync(Supplier supplier) or supplyAsync(Supplier supplier, Executor executor) :返回
CompletableFuture<U>
这个与上面区别就是有返回值
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
System.out.println(Thread.currentThread().getName() + ": runAsync=======开始");
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + ": runAsync=======结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "我是返回值";
});
System.out.println("+++++++++++++++++++++++++++++++");
try {
System.out.println(future.get());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("-------------");
}
通过get()方法,获取返回值。
anyOf(CompletableFuture<?>... cfs): 返回CompletableFuture<Object>
返回先结束的线程,类似之前学的invokeAny.
public static void main(String[] args) {
CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(CompletableFuture.runAsync(() -> {
try {
System.out.println(Thread.currentThread().getName() + ": 1====开始");
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + ": 1====结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}),
CompletableFuture.supplyAsync(() -> {
try {
System.out.println(Thread.currentThread().getName() + ": 2====开始");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + ": 2====结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "ssssssssssssss";
})
);
try {
System.out.println("获取返回值:" + objectCompletableFuture.get());
} catch (Exception e) {
e.printStackTrace();
}
}
输出结果:
注意:当快的线程结束返回结果了,慢的线程照常运行。这里是因为快的线程结束后,get()方法取到值,放行,Main方法就结束了。这时所以全部结束(因为是守护线程)。
(CompletableFuture<?>... cfs):CompletableFuture<Void>
结束的所有线程,类似之前学的invokeAll.
public class CompletableFutureTest1 {
public static void main(String[] args) {
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(CompletableFuture.runAsync(() -> {
try {
System.out.println(Thread.currentThread().getName() + ": 1====开始");
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + ": 1====结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}),
CompletableFuture.supplyAsync(() -> {
try {
System.out.println(Thread.currentThread().getName() + ": 2====开始");
TimeUnit.SECONDS.sleep(10);
System.out.println(Thread.currentThread().getName() + ": 2====结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "ssssssssssssss";
})
);
try {
System.out.println("返回值:" + voidCompletableFuture.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
返回结果:
completedFuture(U value):返回CompletableFuture<U>
public static void main(String[] args) {
CompletableFuture<String> sss = CompletableFuture.completedFuture("sss");
try {
System.out.println(sss.get());
} catch (Exception e) {
e.printStackTrace();
}
}