CompletableFuture的作用
CompletableFuture 在JDK1.8新出的并发工具类,是对于Future Callable的JDK1.5的升级和优化。
常用API
1.CompletableFuture的常用静态方法。 如图:
方法名 | 是否支持自定义线程池 | 是否可以返回线程执行结果 | 是否可进行聚合操作 | 是否异步 |
---|---|---|---|---|
runAsync(Runnable run) | 不支持自定义线程池,是由 ForkJoinPool.commonPool() 默认是3个线程 | 不返回线程执行的结果 | 可以进行聚合操作 | 是 |
runAsync(Runnable run,Executor executor) | 支持自定义线程池 | 不返回线程执行的结果 | 可以进行聚合操作 | 是 |
supplyAsync(Runnable run) | 不支持自定义线程池 | 返回线程执行的结果 | 可以进行聚合操作 | 是 |
supplyAsync(Runnable run,Executor executor)) | 不支持自定义线程池 | 返回线程执行的结果 | 可以进行聚合操作 | 是 |
completedFuture(U value) | 这里不含有自定义线程池,只是CompetableFuture的静态构建方法,返回一个CompetableFuture | 返回线程执行的结果 | 可以进行聚合操作 | 否 |
allOf(CompletableFuture<?>… cfs) | 这里是传入一个CompletableFuture数组,然后同时执行 | 返回线程执行的结果 | 可以进行聚合操作 | 是 |
本类的使用方式:
package chenyi.dubbo.test.compaltableFu;
import groovy.util.logging.Slf4j;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class TestComplateableFutrure {
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2000),
new ThreadFactory() {
AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
return new Thread(r,"Test-"+atomicInteger.incrementAndGet());
}
},new ThreadPoolExecutor.AbortPolicy());
@Test
public void testRunAsync(){
CompletableFuture.runAsync(() -> System.out.println(Thread.currentThread().getName()+"run aync"));
}
@Test
public void testRunAsyncWithExecutor(){
CompletableFuture.runAsync(() -> System.out.println( Thread.currentThread().getName()+"run aync with Executor"),executor);
CompletableFuture.runAsync(() -> System.out.println( Thread.currentThread().getName()+"run aync with Executor"),executor);
CompletableFuture.runAsync(() -> System.out.println( Thread.currentThread().getName()+"run aync with Executor"),executor);
CompletableFuture.runAsync(() -> System.out.println( Thread.currentThread().getName()+"run aync with Executor"),executor);
}
@Test
public void testSuppAsync(){
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() ->{
System.out.println(Thread.currentThread().getName() +" " + "supplyAsync");
if (true){
throw new RuntimeException("我要扔异常了");
}
return "1111";
}).whenComplete((String result,Throwable ex)->{
if (ex !=null){
System.out.println(Thread.currentThread().getName() +" execption " + ex.getMessage() );
}
System.out.println(Thread.currentThread().getName() + " result = " + result);
});
}
@Test
public void testSuppAsyncWithExecut(){
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() ->{
System.out.println(Thread.currentThread().getName() +" " + "supplyAsync");
if (true){
throw new RuntimeException("我要扔异常了");
}
return "1111";
},executor).whenComplete((String result,Throwable ex)->{
if (ex !=null){
System.out.println(Thread.currentThread().getName() +" execption " + ex.getMessage() );
}
System.out.println(Thread.currentThread().getName() + " result = " + result);
});
}
@Test
public void testCompletableFutrue(){
//此处可以传递一个类型,然后被消费处理 或者传递一个方法,通过方法的形式处理 但是此处是无法使用异步处理的。
CompletableFuture.completedFuture("手动阀").whenComplete((String result,Throwable ex)->{
if (ex !=null){
System.out.println(Thread.currentThread().getName() +" execption " + ex.getMessage() );
}
System.out.println(Thread.currentThread().getName() + " result = " + result);
});
}
@Test
public void testAllOf() throws Exception{
List<CompletableFuture> futures = new ArrayList<>();
CompletableFuture[] completableFutures = new CompletableFuture[100];
for (int i = 0; i < 100; i++) {
final Integer t = i;
futures.add(CompletableFuture.supplyAsync(()-> {
try {
Thread.sleep(10* (100 -t));
System.out.println(Thread.currentThread().getName() + " " + t);
} catch (InterruptedException e) {
e.printStackTrace();
}
return t;
},executor));
}
futures.toArray(completableFutures);
CompletableFuture.allOf(completableFutures).join();
for (int i = 0; i < completableFutures.length; i++) {
System.out.println(completableFutures[i].get());
}
}
}