在精通多线程,没用过CompletableFuture(一)中,我们简单介绍了Future和CompletAbleFuture的基本概念和使用小Demo,这里来和大家一起介绍下使用CompletableFuture创建异步任务的四种方式。
创建CompletableFuture对象CompletableFuture提供了四个静态方法用来创建CompletableFuture对象:
public static CompletableFuturerunAsync(Runnable runnable) public static CompletableFuture runAsync(Runnable runnable, Executor executor) public static CompletableFuture supplyAsync(Supplier supplier) public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)
接下来,我们通过四个小Demo来分别演示下
- runAsync不显示配置线程池
@Test
public void testRunAsyncWithOutExecutor() {
CompletableFuture future = CompletableFuture.runAsync(() -> {
System.out.println("开启异步,没有使用定义线程池,没有返回值"+Thread.currentThread().getName());
});
}
执行结果如下
开启异步,没有使用定义线程池,没有返回值ForkJoinPool.commonPool-worker-1
使用runAsync方法创建的CompletableFuture对象没有返回值,并且在创建的时候没有显示指定线程池,所以默认使用了ForkJoinPool.commonPool提供的线程来执行异步任务,一般在开发中,我们还是使用显示的定义线程池比较好,那如何使用自己定义的线程池呢?
- runAsync使用自定义线程池
@Test
public void testRunAsyncWithExecutor() {
ExecutorService executorService = Executors.newSingleThreadExecutor();
CompletableFuture future = CompletableFuture.runAsync(() -> {
System.out.println("开启异步,没有返回值"+Thread.currentThread().getName());
}, executorService);
}
执行结果如下
开启异步,没有返回值pool-1-thread-1
上面executorService是在方法内部定义的一个单一线程池,只是为了演示使用,在实际开发中,我们不要使用这种方式来创建线程池,具体原因参见之前写的禁用Executors创建线程池 。上面两种方法都是不带返回值的,如果异步任务需要返回值,那我们怎么处理呢?
- supplyAsync不显示配置线程池
@Test
public void testSupplyAsyncWithOutExecutor() throws ExecutionException, InterruptedException {
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
System.out.println("开启异步,没有使用定义线程池"+Thread.currentThread().getName());
return "爱琴孩";
});
String name = future.get();
System.out.println("获取异步任务结果" + name);
}
执行结果如下
开启异步,没有使用定义线程池ForkJoinPool.commonPool-worker-1 获取异步任务结果爱琴孩
同样,这里也没有传入线程池参数。
- supplyAsync使用自定义线程池
@Test
public void testSupplyAsyncWithExecutor() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
System.out.println("开启异步"+Thread.currentThread().getName());
return "爱琴孩";
}, executorService);
String name = future.get();
System.out.println("获取异步任务结果" + name);
}
执行结果如下
开启异步pool-1-thread-1 获取异步任务结果爱琴孩总结
上面分别演示了创建CompletableFuture对象的四种方式,其实很简单,在实际开发中根据需求使用便Ok了



