测试代码
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@Slf4j
@DisplayName("新一代异步")
public class CompletableFutureTest {
private static ExecutorService executorService;
@BeforeAll
public static void beforeAll() {
log.info("beforeAll , create executorService");
executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime()
.availableProcessors() * 5, 10, TimeUnit.MINUTES, new ArrayBlockingQueue<>(Runtime.getRuntime()
.availableProcessors() * 500));
}
@AfterAll
public static void afterAll() {
try {
boolean b = executorService.awaitTermination(5L, TimeUnit.SECONDS);
log.info("executorService shutdown ");
if (ObjectUtil.equal(b, false)) {
throw new RuntimeException("5秒内终止失败");
}
}
catch (Exception e) {
executorService.shutdownNow();
}
//在所有测试方法运行完毕后运行
log.info("Run after all test methods have finished running");
}
/**
* run 是没有值.
*/
@Test
public void testRunAsync() {
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> log.info("testRunAsync"), executorService);
completableFuture.join();
log.info("success");
}
/**
* supply是有返回值
*/
@Test
public void testSupplyAsync() {
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
log.info("testRunSupply");
return 100;
}, executorService);
Integer result = completableFuture.join();
log.info("success , result = {}", result);
}
/**
* 任意一个 , 返回值是对应的值
*/
@Test
public void testAnyOf() {
CompletableFuture<Void> first = CompletableFuture.runAsync(() -> {
log.info("testRunAsync");
try {
Thread.sleep(2000L);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, executorService);
CompletableFuture<Integer> second = CompletableFuture.supplyAsync(() -> {
log.info("testRunSupply");
try {
Thread.sleep(3000L);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
return 100;
}, executorService);
Object result = CompletableFuture.anyOf(first, second).join();
log.info("result = {}", result);
}
/**
* AllOf 是所有 , 注意返回值这个时候就会为空了
*/
@Test
public void testAllOf() {
CompletableFuture<Integer> first = CompletableFuture.supplyAsync(() -> {
log.info("testRunAsync");
return 200;
}, executorService);
CompletableFuture<Integer> second = CompletableFuture.supplyAsync(() -> {
log.info("testRunSupply");
return 100;
}, executorService);
Object result = CompletableFuture.allOf(first, second).join();
log.info("result = {}", result);
}
/**
* 执行 , 不使用上一个的返回值参数.
* 下一个感知不到上一个的异常
*/
@Test
public void testThenRun() {
CompletableFuture<Integer> first = CompletableFuture.supplyAsync(() -> {
log.info("testRunAsync");
return 200;
}, executorService);
first.thenRun(() -> log.info("then run "));
first.join();
}
/**
* 执行,使用上一个的返回参数,无返回值
* 下一个感知不到上一个的异常
*/
@Test
public void testThenRAccept() {
CompletableFuture<Integer> first = CompletableFuture.supplyAsync(() -> {
log.info("testRunAsync");
return 200;
}, executorService);
first.thenAccept((x) -> {
log.info("before result ={}", x);
log.info("then run ");
});
first.join();
}
/**
* 执行,使用上一个的返回参数,并且返回自己对应的值
* 下一个感知不到上一个的异常
*/
@Test
public void testThenApply() {
CompletableFuture<Integer> first = CompletableFuture.supplyAsync(() -> {
log.info("testRunAsync");
return 200;
}, executorService);
CompletableFuture<Integer> second = first.thenApplyAsync((x) -> {
log.info("before result ={}", x);
log.info("then run ");
return 800;
}, executorService);
Integer firstResult = first.join();
Integer secondResult = second.join();
log.info("firstResult = {} ,secondResult ={} ", firstResult, secondResult);
}
/**
* whenComplete : 可以感知到异常,并且能够执行下面的业务方法
*/
@Test
public void testWhenComplete() {
CompletableFuture<Integer> first = CompletableFuture.supplyAsync(() -> {
log.info("testRunAsync");
// int i = 1 / 0;
return 200;
}, executorService);
CompletableFuture<Integer> second = first.whenComplete((x, e) -> {
log.info("error , ", e);
log.info("result = {}", x);
});
second.join();
log.info("succes");
}
/**
* handle 能够处理异常,并且返回结果
* 注意join 如果本身有异常,如果不捕获,那么就会直接往外面抛异常,比如下面的处理,second就会执行完
*/
@Test
public void testHandle() {
CompletableFuture<Integer> first = CompletableFuture.supplyAsync(() -> {
log.info("testRunAsync");
// int i = 1 / 0;
return 200;
}, executorService);
CompletableFuture<Integer> second = first.handle((x, e) -> {
log.info("error , 异常了 ", e);
log.info("second 业务执行= {}", x);
return 400;
});
Integer secondResult = second.join();
log.info("secondResult={} ", secondResult);
Integer firstResult = first.join();
log.info("firstResult = {} ", firstResult);
}
}
CompleteableFuture知识点
介绍:用于异步编程, 是Future的扩展
注意点:我们在使用时建议使用带executor的方法(保证线程不会无限创建)
创建异步任务
supplyAsync(Supplier supplier)
supplyAsync(Supplier supplier, Executor executor)
特点:有返回的异步任务
runAsync(Runnable runnable)
runAsync(Runnable runnable, Executor executor)
特点:无返回值的任务
异步任务回调
thenRun(Runnable action)
thenRunAsync(Runnable action)
thenRunAsync(Runnable action, Executor executor)
特点 : 无返回值的任务回调 ; 没法获取上一个任务的返回值;没法感知上一个任务的异常
thenAccept(Consumer action)
thenAcceptAsync(Consumer action)
thenAcceptAsync(Consumer action, Executor executor)
特点:无返回值的任务回调 ; 能获取上一个任务的返回值;没法感知上一个任务的异常
thenAccept,thenAcceptAsync : thenAccept用的是上一个任务的线程池,thenAcceptAsync用的是系统默认的线程池
whenComplete
whenComplete(BiConsumer action)
whenCompleteAsync(BiConsumer action)
whenCompleteAsync(BiConsumer action,Executor executor)
特点:无返回值的任务回调 ; 能获取上一个任务的返回值 ;能够获取到上一个任务的异常
whenComplete,whenCompleteAsync : whenComplete用的是上一个任务的线程池,whenCompleteAsync用的是系统默认的线程池
handle
handle(BiFunction fn))
handleAsync(BiFunction fn))
handle(BiFunction fn,Executor executor)
特点:有返回值的任务回调 ; 能获取上一个任务的返回值 ;能够获取到上一个任务的异常
handle,handleAsync : handle用的是上一个任务的线程池,handleAsync用的是系统默认的线程池
异常
exceptionally(Function fn)
exceptionallyAsync(Function fn)
exceptionallyAsync(Function fn,Executor executor)
特点:异常的显示以及处理
exceptionally,exceptionallyAsync : handle用的是上一个任务的线程池,handleAsync用的是系统默认的线程池