package future;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author XRZ
* @date 2020/6/15 18:05
* @Description :
*/
public class FutureTest {
private ThreadPoolExecutor executor;
@Before
public void init(){
executor = new ThreadPoolExecutor(
2,
4,
30,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>()
);
}
@After
public void waitAsync() throws InterruptedException {
Thread.sleep(5000);
}
@Test
public void cretae_CompletableFuture() throws Exception {
/**
* CompletableFuture.runAsync(Runnable runnable);
*/
CompletableFuture.runAsync(() -> {
System.out.println(Thread.currentThread().getName()+"======>无返回值异步线程,使用JDK默认线程池执行:ForkJoinPool.commonPool()");
});
/**
* CompletableFuture.runAsync(Runnable runnable, Executor executor);
*/
CompletableFuture.runAsync(() -> {
System.out.println(Thread.currentThread().getName()+"======>无返回值异步线程,使用指定线程池执行");
},executor);
/**
* CompletableFuture.supplyAsync(Supplier<U> supplier);
*/
CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {
return Thread.currentThread().getName()+"======>有返回值异步线程,使用JDK默认线程池执行:ForkJoinPool.commonPool()";
});
System.out.println(completableFuture1.get());
/**
* CompletableFuture.supplyAsync(Supplier<U> supplier, Executor executor)
*/
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
return Thread.currentThread().getName() + "======>有返回值异步线程,使用指定线程池执行";
}, executor);
System.out.println(completableFuture2.get());
// ForkJoinPool.commonPool-worker-1======>无返回值异步线程,使用JDK默认线程池执行:ForkJoinPool.commonPool()
// pool-1-thread-1======>无返回值异步线程,使用指定线程池执行
// ForkJoinPool.commonPool-worker-1======>有返回值异步线程,使用JDK默认线程池执行:ForkJoinPool.commonPool()
// pool-1-thread-2======>有返回值异步线程,使用指定线程池执行
}
@Test
public void get_CompletableFuture() throws Exception {
/**
* CompletableFuture.get() 获取结果
*/
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "result");
System.out.println(future1.get());
/**
* CompletableFuture.getNow(T valueIfAbsent) 获取结果,如果在执行getNow的时候,还未返回结果或者抛了异常,返回valueIfAbsent
*/
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "result");
Thread.sleep(500);
System.out.println(future2.getNow("res"));
/**
* CompletableFuture.get(long timeout, TimeUnit unit) 获取结果,如果超过等待时间,throw TimeoutException
*/
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "result";
});
System.out.println(future3.get(1,TimeUnit.SECONDS));
// result
// result
//
// java.util.concurrent.TimeoutException
}
@Test
public void complete_CompletableFuture() throws Exception {
/**
* complete(T t) :结束异步线程,返回T(多次调用以第一次为准)
*/
CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> "RESULT");
completableFuture1.complete("结束异步线程,返回指定结果");
System.out.println(completableFuture1.get());
/**
* completeExceptionally(Throwable ex) :结束异步线程,返回一个异常
*/
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> "RESULT");
// Thread.sleep(1000);
completableFuture2.completeExceptionally(new RuntimeException("结束异步线程,返回自定义异常"));
System.out.println(completableFuture2.get());
/**
* 如果异步线程比主线程先执行完成,则正常返回,complete/completeExceptionally 失效
*/
// 结束异步线程,返回指定结果
//
// java.util.concurrent.ExecutionException: java.lang.RuntimeException: 结束异步线程,返回自定义异常
}
@Test
public void thenApply_CompletableFuture() throws Exception{
/**
* 结果转换 T -> U
* thenApply(Function<? super T,? extends U> fn)
* thenApplyAsync(Function<? super T,? extends U> fn)
* thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
*/
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> "RESULT")
.thenApply(res -> res + "Convert")
.thenApply(String::length);
System.out.println(future.get());
// 13
}
@Test
public void whenComplete_CompletableFuture() throws Exception{
/**
* 对结果的处理
* whenComplete(BiConsumer<? super T,? super Throwable> action)
* whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
* whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
*/
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 1/0)
.whenComplete((res, e) -> {
System.out.println("RESULT:"+res);
System.out.println("异常信息:"+e);
});
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 1/1)
.whenComplete((res, e) -> {
System.out.println("RESULT:"+res);
System.out.println("异常信息:"+e);
});
System.out.println(future2.get());
// RESULT:null
// 异常信息:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
// RESULT:1
// 异常信息:null
// 1
}
@Test
public void handle_CompletableFuture() throws Exception{
/**
* 对结果的处理并且转换
* handle(BiFunction<? super T, Throwable, ? extends U> fn)
* handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
* handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
*/
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> 1/1)
.handle((res, e) -> {
System.out.println("RESULT:"+res);
System.out.println("异常信息:"+e);
return "RESULT";
});
System.out.println(future2.get());
// RESULT:1
// 异常信息:null
// RESULT
}
@Test
public void thenAccept_CompletableFuture() throws Exception{
/**
* thenAccept(Consumer<? super T> action)
* thenAcceptAsync(Consumer<? super T> action)
* thenAcceptAsync(Consumer<? super T> action, Executor executor)
*/
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> "RESULT")
.thenAccept(res -> {
System.out.println("消费结果且无返回:"+res);
});
System.out.println(future.get()); //null
// 消费结果且无返回:RESULT
// null
}
@Test
public void thenRun_CompletableFuture() throws Exception{
/**
* thenRun(Runnable action)
* thenRunAsync(Runnable action)
* thenRunAsync(Runnable action, Executor executor)
*/
CompletableFuture.runAsync(() -> {
System.out.println("异步线程方法执行1");
}).thenRun(() -> {
System.out.println("异步线程方法执行2");
}).thenRun(() -> {
System.out.println("异步线程方法执行3");
});
// 异步线程方法执行1
// 异步线程方法执行2
// 异步线程方法执行3
}
}