package com.baomidou.mybatisplus.samples.ar;
import org.junit.Test;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestDemo01 {
//线程池在,会让主线程一直处于等待状态
public static ExecutorService executor = Executors.newFixedThreadPool(10);
/**
* CompletableFuture
* 1.提供了四个静态方法来创建一个异步操作
* runAsync 无返回值的任务,也可以指定线程池
* supplyAsync 有返回值的任务,也可以指定线程池
* runXxxx都是没有返回值的,supplyXxxx都是有返回值的
* 可以指定线程池,否则就使用默认的线程池
*/
@Test
public void test01() throws ExecutionException, InterruptedException {
//无返回值的异步任务
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
System.out.println("运行结果" + 10 / 2);
}, executor);
//有返回值的异步任务
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
System.out.println("运行结果" + 10 / 0);
return 10 / 2;
}, executor);
System.out.println(future1.get());
}
/**
* 2.异步方法完成后的感知,处理
* whenComplete exceptionally handle;带Async后缀的是使用新的线程执行,还可以指定线程池
*/
@Test
public void test02() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
System.out.println("运行结果" + 10 / 0);
return 10 / 2;
}, executor).whenComplete((result, exception) -> {
//可以得到结果,和异常信息,无返回值
System.out.println("异步任务成功完成了。。结果是" + result + "异常是" + exception);
}).exceptionally(throwable -> {
//可以感知异常,有返回值
return 3;
}).handle((result, exception) -> {
//可以得到结果,和异常信息,有返回值
if(Objects.nonNull(result)) return result * 2;
if(Objects.nonNull(exception)) return 0;
return 2;
});
System.out.println("future的结果" + future.get());
}
@Test
public void test03() {
}
/**
* 4.线程串行化
* 有一系列方法,thenRun thenAccept thenApply;xxxAsync 使用新线程执行,可指定参数线程池
* (1).thenRun参数为Runnable 无法感知上一步的执行结果
* (2).thenAccept参数为Consumer 可以感知上一步的执行结果,但不返回本步骤的执行结果
* (3).thenApply参数为Function 可以感知上一步的执行结果,并返回本步骤的执行结果
*/
@Test
public void test04() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
System.out.println("运行结果" + 10 / 5);
return 10 / 2;
}, executor).thenRunAsync(() -> {
System.out.println("任务2启动了");
}, executor).thenAcceptAsync(res -> {
System.out.println("任务3启动了" + res);
}).thenApplyAsync(res -> {
System.out.println("任务4启动了" + res);
return 1;
});
System.out.println(future.get());
}
/**
* 5.两任务组合
* 有一系列方法
*/
@Test
public void test05() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
return 10 / 2;
}, executor);
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
return "hello";
}, executor);
//不感知结果,无返回值
future1.runAfterBothAsync(future2, () -> {
System.out.println("任务3开始");
}, executor);
//感知前两部的结果,无返回值
future1.thenAcceptBothAsync(future2, (f1, f2) -> {
System.out.println("任务4开始。。之前的结果::" + f1 + "==》" + f2);
}, executor);
//感知前两部的结果,有返回值
CompletableFuture<String> future = future1.thenCombineAsync(future2, (f1, f2) -> {
return f1 + ":" + f2;
}, executor);
System.out.println(future.get());
}
/**
* 6.两任务组合,只要有一个完成,就执行下一个任务
* 感知结果时,任务结果的类型需要一致
*/
@Test
public void test06() throws ExecutionException, InterruptedException {
CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
return 10 / 2;
}, executor);
CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
System.out.println("任务2线程结束:" + Thread.currentThread().getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hello";
}, executor);
//不感知结果,无返回值
future1.runAfterEitherAsync(future2, () -> {
System.out.println("任务3");
}, executor);
//感知结果,无返回值
future1.acceptEitherAsync(future2, res -> {
System.out.println(res);
}, executor);
//感知结果,有返回值
CompletableFuture<String> future = future1.applyToEitherAsync(future2, res -> {
return res + "有返回值";
}, executor);
System.out.println(future.get());
}
/**
* 7.多任务组合,工作中用的较多
* CompletableFuture的allOf方法,等待所有任务执行完成
*/
@Test
public void test07() throws ExecutionException, InterruptedException {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品图片信息");
return "hello.jpg";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品属性");
return "黑色";
});
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品品牌");
try {
Thread.sleep(3000);
System.out.println("查询商品品牌结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "OPPO";
});
//
CompletableFuture<Void> future = CompletableFuture.allOf(future1, future2, future3);
//等待结果
future.get();
// future.join();
//取结果
System.out.println(future1.get()+future2.get()+future3.get());
System.out.println("main....end");
}
public static void main(String[] args) {}
}
http://www.gulixueyuan.com/course/370/task/13477/show