目录
注意!!!:强烈建议手动创建线程池,这里为了方便演示所以直接Java提供的线程池
若想学习手动创建线程池欢迎观看我的另一篇博客《手动创建线程池》
1.无返回的异步任务
1.1.runAsync();
//警告:强烈建议手动创建线程池,这里为了方便演示所以直接Java提供的线程池
//若想学习手动创建线程池欢迎观看我的另一篇博客《手动创建线程池》
public static ExecutorService executor = Executors.newFixedThreadPool(10);
@Test
public void demo(){
//无返回值异步任务
CompletableFuture.runAsync(() -> {
System.out.println("当前线程: " + Thread.currentThread().getId());
int t = 10 / 2;
System.out.println("运行结果: " + t);
}, executor);
}
控制台输出:
当前线程: 33
运行结果: 5
2.有返回值的异步任务
2.2.supplyAsync();
@Test
public void demo() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程: " + Thread.currentThread().getId());
int t = 10 / 2;
System.out.println("运行结果: " + t);
return t;
}, executor);
Integer integer = future.get();
System.out.println("返回值为: " + integer);
}
控制台输出:
当前线程: 33
运行结果: 5
返回值为: 5
3.有返回值+异常信息的异步任务
3.1.whenComplete():虽然能得到异常信息,但是没法修改返回的数据;(此文章只演示该方法)
3.2.exceptionally():可以感知异常,同时返回默认值;
@Test
public void demo() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程: " + Thread.currentThread().getId());
int t = 10 / 0;//故意弄了一个BUG
System.out.println("运行结果: " + t);
return t;
}, executor).whenComplete((res, err) -> {
//虽然能得到异常信息,但是没法修改返回的数据
System.out.println("异步任务成功完成了..结果是: " + res + ";异常是:" + err);
}).exceptionally(throwable -> {
//可以感知异常,同时返回默认值;
return 6666;
});
Integer integer = future.get();
System.out.println("返回的结果: " + integer);
}
控制台输出:
当前线程: 33
异步任务成功完成了..结果是: null;异常是:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
返回的结果: 6666
4.线程串行化,能接收上一步结果,但是无返回值
4.1.thenAcceptAsync();
@Test
public void demo() throws ExecutionException, InterruptedException {
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程: " + Thread.currentThread().getId());
int t = 10 / 2;
System.out.println("运行结果: " + t);
return t;
}, executor).thenAcceptAsync(res -> {
System.out.println("任务2启动,接收到上一步的结果是:" + res);
}, executor);
}
控制台输出:
当前线程: 33
运行结果: 5
任务2启动,接收到上一步的结果是:5
5. 线程串行化,能接收上一步结果,并且有返回值
5.1.thenApplyAsync();
@Test
public void demo() throws ExecutionException, InterruptedException {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程: " + Thread.currentThread().getId());
int t = 10 / 2;
System.out.println("运行结果: " + t);
return t;
}, executor).thenApplyAsync(res -> {
System.out.println("任务2启动...接收到上一步的结果:" + res);
return "Hello: " + res;
}, executor);
System.out.println("返回的东西是: " + future.get());
}
控制台输出:
当前线程: 33
运行结果: 5
任务2启动...接收到上一步的结果:5
返回的东西是: Hello: 5
6.两任务组合服务,两个都完成才往下执行
6.1.runAfterBothAsync(): 组合但是没有返回值;
6.2.thenAcceptBothAsync: 组合有返回值;
6.3.thenCombineAsync: 组合有返回值,并且可以更改数据;(此文章只演示该方法)
@Test
public void demo() throws ExecutionException, InterruptedException {
//第一个任务
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1: " + Thread.currentThread().getId());
int t = 10 / 2;
System.out.println("运行结果1: " + t);
return t;
}, executor);
//第二个任务
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程2: " + Thread.currentThread().getId());
System.out.println("运行结果2: ");
return "Hello";
}, executor);
/*
*组合
* .runAfterBothAsync(): 组合但是没有返回值
* .thenAcceptBothAsync: 组合有返回值
* .thenCombineAsync: 组合有返回值,并且可以更改数据
*/
CompletableFuture<String> future = future1.thenCombineAsync(future2, (f1, f2) -> {
return "组合技:" + f1 + f2;
}, executor);
System.out.println("最后组合返回的参数:" + future.get());
}
控制台输出:
当前线程1: 33
运行结果1: 5
当前线程2: 34
运行结果2:
最后组合返回的参数:组合技:5Hello
7.两任务组合服务,完成其中一个
7.1.runAfterEitherAsync: 不感知结果,自己没有返回值;
7.2.acceptEitherAsync: 感知结果,自己没有返回值.注:两个任务的返回值类型必须一致;
7.3.applyToEitherAsync:感知结果,有返回值;(此文章只演示该方法)
@Test
public void demo() throws ExecutionException, InterruptedException {
//第一个任务
CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1: " + Thread.currentThread().getId());
int t = 10 / 2;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("运行结果1: " + t);
return t;
}, executor);
//第二个任务
CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程2: " + Thread.currentThread().getId());
System.out.println("运行结果2: ");
return "Hello";
}, executor);
/*
*.runAfterEitherAsync: 不感知结果,自己没有返回值
* .acceptEitherAsync: 感知结果,自己没有返回值.注:两个任务的返回值类型必须一致
*
*/
CompletableFuture<String> future = future1.applyToEitherAsync(future2, (res) -> {
return res.toString() + "添加自己的特色";
}, executor);
System.out.println(future.get());
}
控制台输出:
当前线程1: 33
当前线程2: 34
运行结果2:
Hello添加自己的特色
8.多组合,等待所有方法都执行完,才往下执行
8.1.allOf();
@Test
public void demo() throws ExecutionException, InterruptedException {
Map<String, String> map = new HashMap<>();
//第一个任务
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的图片信息");
map.put("照片信息", "lisa.jpg");
return "lisa.jpg";
}, executor);
//第二个任务
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的属性");
map.put("商品的属性", "黑色+256G");
return "黑色+256G";
}, executor);
//第三个任务
CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品介绍");
map.put("商品介绍", "华为");
return "华为";
}, executor);
CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
allOf.get();//虽然没办法获取数据,但是需要他阻塞main方法的线程,防止异步线程还没执行完,main方法就先结束了
String result = futureImg.get() + futureAttr.get() + futureDesc.get();
System.out.println("获取到的返回值数据为:"+result);
System.out.println("map收集到的数据为:"+map.toString());
}
控制台输出:
查询商品的图片信息
查询商品的属性
查询商品介绍
获取到的返回值数据为:lisa.jpg黑色+256G华为
map收集到的数据为:{商品的属性=黑色+256G, 商品介绍=华为, 照片信息=lisa.jpg}
9.多组合,其中只要有一个方法执行完成边可往下执行
9.1.anyOf();
@Test
public void demo() throws ExecutionException, InterruptedException {
Map<String, String> map = new HashMap<>();
//第一个任务
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的图片信息");
map.put("照片信息", "lisa.jpg");
return "lisa.jpg";
}, executor);
//第二个任务
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的属性");
map.put("商品的属性", "黑色+256G");
return "黑色+256G";
}, executor);
//第三个任务
CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品介绍");
map.put("商品介绍", "华为");
return "华为";
}, executor);
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
Object result = anyOf.get();
System.out.println("获取到的返回值数据为:"+result);
System.out.println("map收集到的数据为:"+map.toString());
}
控制台输出:
查询商品的图片信息
查询商品的属性
获取到的返回值数据为:lisa.jpg
map收集到的数据为:{商品的属性=黑色+256G, 照片信息=lisa.jpg}
查询商品介绍