共计 4536 个字符,预计需要花费 12 分钟才能阅读完成。
1.CompletableFuture 的办法简介和应用
2. 总结
1.CompletableFuture 的办法简介和应用
从下面那篇博客 JAVA 并发编程——Future 和 CompletableFuture 的简介与应用 咱们对 CompletableFuture 有了一个大略的理解和初步的应用,接下来咱们来零碎介绍一下 CompletableFuture 这个类有哪些办法。
1.0 根底的运行办法
// 无返回值, 相似 Runnable 可抉择传入一个线程池
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)
// 有返回值,相似 Future 可抉择传入一个线程池
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
1.1 取得后果和触发计算的办法
public T get();// 始终阻塞获取后果,和 Future 的 get()办法雷同
public T get(long timeout, TimeUnit unit);// 在肯定工夫内获取后果,没取得后果就抛异样
public T getNow(T valueIfAbsent);// 马上获取后果,如果没获取到后果就返回传入参数的默认值。
public T join(); // 和 get()办法雷同,区别是 join()不会抛出异样,get()会抛出异样
public boolean complete(T value) // 在计算未实现的状况下,立即打断 get 办法立刻返回括号值
1.2 对计算结果进行解决的办法
thenApply()
// 计算结果存在依赖关系,先执行上一步再执行下一步
// 因为存在依赖关系(以后步错,不走下一步),以后步骤有异样的话就叫停。
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
{
// 当一个线程依赖另一个线程时用 thenApply 办法来把这两个线程串行化,
CompletableFuture.supplyAsync(() -> {
// 暂停几秒钟线程
try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
System.out.println("111");
return 1024;
}).thenApply(f -> {System.out.println("222");
return f + 1;
}).thenApply(f -> {
//int age = 10/0; // 异常情况:那步出错就停在那步。System.out.println("333");
return f + 1;
}).whenCompleteAsync((v,e) -> {// 当实现的时候
System.out.println("*****v:"+v);
}).exceptionally(e -> {// 当产生异样的时候
e.printStackTrace();
return null;
});
System.out.println("----- 主线程完结,END");
// 主线程不要立即完结,否则 CompletableFuture 默认应用的线程池会立即敞开:
try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace(); }
}
}
// 有异样也能够往下一步走,依据带的异样参数能够进一步解决
handle()
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
{
// 当一个线程依赖另一个线程时用 handle 办法来把这两个线程串行化,
// 异常情况:有异样也能够往下一步走,依据带的异样参数能够进一步解决
CompletableFuture.supplyAsync(() -> {
// 暂停几秒钟线程
try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
System.out.println("111");
return 1024;
}).handle((f,e) -> {
int age = 10/0;
System.out.println("222");
return f + 1;
}).handle((f,e) -> {System.out.println("333");
return f + 1;
}).whenCompleteAsync((v,e) -> {System.out.println("*****v:"+v);
}).exceptionally(e -> {e.printStackTrace();
return null;
});
System.out.println("----- 主线程完结,END");
// 主线程不要立即完结,否则 CompletableFuture 默认应用的线程池会立即敞开:
try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace(); }
}
}
1.3 对计算结果进行生产的办法
// 接管工作的处理结果,并生产解决,无返回后果
thenAccept();
// 工作 A 执行完执行 B,并且 B 不须要 A 的后果
thenRun();
// 工作 A 执行完执行 B,B 须要 A 的后果,然而工作 B 无返回值
thenAccept();
// 工作 A 执行完执行 B,B 须要 A 的后果,同时工作 B 有返回值
thenApply();
public static void main(String[] args) throws ExecutionException, InterruptedException
{CompletableFuture.supplyAsync(() -> {return 1;}).thenApply(f -> {return f + 2;}).thenApply(f -> {return f + 3;}).thenApply(f -> {return f + 4;}).thenAccept(r -> System.out.println(r));
}
1.4 对计算速度进行选用的办法
// 谁快用谁
applyToEither()
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
{CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
// 暂停几秒钟线程
try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace(); }
return 10;
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
return 20;
});
CompletableFuture thenCombineResult = completableFuture1.applyToEither(completableFuture2,f -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return f + 1;
});
System.out.println(Thread.currentThread().getName() + "\t" + thenCombineResult.get());
}
}
1.5 对计算结果进行合并的办法
// 两个 CompletionStage 工作都实现后,最终能把两个工作的后果一起交给 thenCombine 来解决
thenCombine()
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
{CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return 10;
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return 20;
});
CompletableFuture thenCombineResult = completableFuture1.thenCombine(completableFuture2, (x, y) -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return x + y;
});
System.out.println(thenCombineResult.get());
}
}
2. 总结
这篇博客咱们总结了 CompletableFuture 的根底办法,咱们还是须要在生产上多加练习,遗记 api 的时候能够看一下源码或者从新翻阅一下这篇博客。
正文完