CompletableFuture是java8的新特性:异步编程。
直接上代码(详细说明在代码中):
package com.example.java8.chapter11;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
/**
* 提醒:下面每个方法最后几行注释的代码是此方法在执行时,在console打印的内容
*/
public class FutureTest {
public void delay(int second) {
long time = second * 1000;
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String thing1() {
delay(1);
System.out.println("thing1:方法执行中");
return "thing1返回值";
}
public Integer thing2() {
delay(2);
System.out.println("thing2:方法执行中");
return 100;
}
public String thing3() {
delay(3);
System.out.println("thing3:方法执行中");
return "thing3返回值";
}
public String thing4(String text) {
delay(4);
System.out.println("参数:" + text);
System.out.println("thing4:方法执行中");
return "thing4返回值";
}
/**有返回结果的异步执行*/
@Test
public void test1() throws Exception {
// 1.异步执行,重新起一个线程去执行新的任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> thing1());
// 2.获取异步执行的结果,限定时间在2秒内(避免无限期等待;如果超过2秒,就会抛出Timeout异常)
String text = future.get(2L, TimeUnit.SECONDS);
// 3.打印结果
System.out.println("结果:" + text);
// thing1:方法执行中
// 结果:thing1返回值
}
/**无返回结果的异步执行*/
@Test
public void test2() throws Exception {
// join方法是为了获取结果;如果不关注结果,可以不调用join方法(异步线程也会执行)
// get方法和join方法效果一样;
// get(Long time) 带参数的get方法表示设置超时,建议使用设置超时的get获取异步执行结果
CompletableFuture.runAsync(() -> thing1()).join();
// thing1:方法执行中
}
@Test
public void test3() {
// 等待第一个异步执行完毕后,得到异步执行结果继续执行,没有返回值
CompletableFuture<Void> accept = CompletableFuture.supplyAsync(() -> thing1())
.thenAccept(e -> System.out.println("包装结果:" + e));
accept.join();
// thing1:方法执行中
// 包装结果:thing1返回值
}
@Test
public void test4() {
// 等待第一个方法执行完毕,然后第二方法执行完毕,接着处理方法1和方法2的结果,没有返回值
CompletableFuture<Void> acceptBoth = CompletableFuture.supplyAsync(() -> thing1())
.thenAcceptBoth(CompletableFuture.supplyAsync(() -> thing3()), (e1, e2) -> System.out.println(e1 +" "+ e2));
acceptBoth.join();
// thing1:方法执行中
// thing3:方法执行中
// thing1返回值 thing3返回值
}
@Test
public void test5() {
// 等待第一个异步执行完毕后,得到异步执行结果继续执行,有返回值(和thenAccept相似,区别就是有返回值)
CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(() -> thing1())
.thenApply((t) -> {
System.out.println(t);
return 999;
});
thenApply.join();
// thing1:方法执行中
// thing1返回值
}
@Test
public void test6() {
// 等待第一个方法执行完毕,然后第二方法执行完毕,接着处理方法1和方法2的结果,有返回值(和thenAcceptBoth相似,区别就是有返回值)
CompletableFuture<String> thenCombine = CompletableFuture.supplyAsync(() -> thing1())
.thenCombine(CompletableFuture.supplyAsync(() -> thing2()), (e1, e2) -> {
System.out.println("e1:" + e1);
System.out.println("e2:" + e2);
return "java";
});
thenCombine.join();
// thing1:方法执行中
// thing2:方法执行中
// e1:thing1返回值
// e2:100
}
@Test
public void test7() {
// 异步方法1执行完毕后,方法1的结果传递给方法2继续执行
CompletableFuture<String> thenCompose = CompletableFuture.supplyAsync(() -> thing1())
.thenCompose(e -> CompletableFuture.supplyAsync(() -> thing4(e)));
thenCompose.join();
// thing1:方法执行中
// 参数:thing1返回值
// thing4:方法执行中
}
@Test
public void test8() {
// 异步方法1执行完毕后,再执行1个action
CompletableFuture.supplyAsync(() -> thing1()).thenRun(() -> System.out.println("执行中")).join();
// thing1:方法执行中
// 执行中
}
@Test
public void test9() {
// 一个异步方法执行完毕后,得到他的返回结果和异常信息进一步处理,最后返回方法1返回结果
String join = CompletableFuture.supplyAsync(() -> thing1()).whenComplete((e1, e2) -> {
System.out.println("e1: 异步请求的结果:" + e1);
System.out.println("e2: 异常:" + e2);
}).join();
System.out.println(join);
// thing1:方法执行中
// e1: 异步请求的结果:thing1返回值
// e2: 异常:null
// thing1返回值
}
@Test
public void test10() {
// 一个异步方法执行完毕后,得到他的返回结果和异常信息进一步处理,最后返回其他类型的结果
CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> thing1()).handle((e1, e2) -> {
System.out.println("e1: 异步请求的结果:" + e1);
System.out.println("e2: 异常:" + e2);
return 300;
});
Integer i = handle.join();
System.out.println(i);
// thing1:方法执行中
// e1: 异步请求的结果:thing1返回值
// e2: 异常:null
// 300
}
}









网友评论