异步编程—CompletableFuture简单使用

虽说到现在所接触的项目慢慢地都开始使用了Java 8了,但是很多时候并没有使用到Java 8中的新特性,还是照着老的用法写😂。这几天碰到的任务恰好需要用到多线程去处理,单个线程耗时太久了,本来是想用最原始的那种方式(继承Thread,实现Runable接口这种),和组内的同事交流了下,组里的同事说了下Future这种方式,在Java 8 中可以使用CompletableFuture这个去优雅的处理多线程的问题,因此这篇文章主要记录下CompletableFuture的简单使用,实践下多线程😁

介绍

image.png

参考这篇文章: Java8新的异步编程方式 CompletableFuture(一)

使用

1.像普通的类一样new 一个对象(实际中不会使用这种方式):

1
2
3
4
5
6
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("begin")
CompletableFuture<String> future = new CompletableFuture<String>();
future.complete("do future task");
System.out.println(future.get());
}

2.使用静态方法:

2.1不需要返回结果(runAsync()):

1
2
3
4
5
6
7
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("begin["+Thread.currentThread().getName()+"]");
CompletableFuture<Void> future = CompletableFuture.runAsync(()->{
System.out.println("do future task ["+Thread.currentThread().getName()+"]");
});
System.out.println("end["+Thread.currentThread().getName()+"]");
}

2.2需要返回结果(supplyAsync()):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("begin["+Thread.currentThread().getName()+"]");
CompletableFuture<String> future =CompletableFuture.supplyAsync(()->{
System.out.println("do future task["+Thread.currentThread().getName()+"]");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "done";
});
System.out.println(future.get());
System.out.println("end["+Thread.currentThread().getName()+"]");
}

需要注意:get()方法是阻塞的,会等到Future执行完才会返回

等待线程执行完再去处理其他任务(例如导入Excel入库后,新增导入历史记录):

thenApplyAsync()

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("begin["+Thread.currentThread().getName()+"]");
Executor executor =Executors.newFixedThreadPool(2);
CompletableFuture<String> future = CompletableFuture.supplyAsync(()->{
System.out.println("supply>>");
return "do future task";
}).thenApplyAsync((re)->{
System.out.println(re+" then sysout");
return "then";
});
System.out.println(future.get());
System.out.println("end["+Thread.currentThread().getName()+"]");
}

目前就用到了这些,后续用到其他“功能”再补充(这篇文章拖了一个清明节假,逃…)


参考文章:

Java 8 CompletableFuture 教程

Java8新的异步编程方式 CompletableFuture(一)