java 异步编程 CompletableFuture
理解同步与异步区别
同步:就是在发出一个功能调用时,在没有得到结果之前,将一直处于等待中 即阻塞状态。也就是必须一件一件事做,等前一件做完了才能做下一件事
异步:异步通常意味着非阻塞,可以使得我们的任务单独运行在与主线程分离的其他线程中,并且通过回调可以在主线程中得到异步任务的执行状态,是否完成,和是否异常等信息。
CompletableFuture 简介
Future 与 CompletableFuture
Future 的主要缺点如下:
CompletableFuture 有 2个 异步方法
runAsync
异步调用有返回值方法
supplyAsync
使用 CompletableFuture
/*** 主线程里面创建一个 CompletableFuture,然后主线程调用 get 方法会阻塞,最后我们在一个子线程中使其终止* @param args*/public static void main(String[] args) throws Exception{CompletableFuture<String> future = new CompletableFuture<>();new Thread(() -> {try{System.out.println(Thread.currentThread().getName() + "子线程开始干活");//子线程睡 5 秒Thread.sleep(5000);//在子线程中完成主线程future.complete("success");}catch (Exception e){e.printStackTrace();}}, "A").start();//主线程调用 get 方法阻塞System.out.println("主线程调用 get 方法获取结果为: " + future.get());System.out.println("主线程完成,阻塞结束!!!!!!");}
public static void main(String[] args) throws Exception {System.out.println("主线程开始");//运行一个没有返回值的异步任务CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {try {System.out.println("子线程启动干活");Thread.sleep(5000);System.out.println("子线程完成");} catch (Exception e) {e.printStackTrace();}});//主线程阻塞future.get();System.out.println("主线程结束");}
/*** 有返回值的异步任务* @param args*/public static void main(String[] args) throws Exception{System.out.println("主线程开始");//运行一个有返回值的异步任务CompletableFuture<String> future =CompletableFuture.supplyAsync(() -> {try {System.out.println("子线程开始任务");Thread.sleep(5000);} catch (Exception e) {e.printStackTrace();}return "子线程完成了!";});//主线程阻塞String s = future.get();System.out.println("主线程结束, 子线程的结果为:" + s);}
线程依赖
private static Integer num = 10;/*** 先对一个数加 10,然后取平方** @param args*/public static void main(String[] args) throws Exception {System.out.println("主线程开始");CompletableFuture<Integer> future =CompletableFuture.supplyAsync(() -> {try {System.out.println("加 10 任务开始");num += 10;} catch (Exception e) {e.printStackTrace();}return num;}).thenApply(integer -> {return num * num;});Integer integer = future.get();System.out.println("主线程结束, 子线程的结果为:" + integer);
thenAccept 消费处理结果, 接收任务的处理结果,并消费处理,无返回结果。
private static Integer num = 10;public static void main(String[] args) throws Exception {System.out.println("主线程开始");CompletableFuture.supplyAsync(() -> {try {System.out.println("加 10 任务开始");num += 10;} catch (Exception e) {e.printStackTrace();}return num;}).thenApply(integer -> {return num * num;}).thenAccept(new Consumer<Integer>() {@Overridepublic void accept(Integer integer) {System.out.println("子线程全部处理完成,最后调用了 accept,结果为:" +integer);}});}
exceptionally 异常处理,出现异常时触发
private static Integer num = 10;public static void main(String[] args) throws Exception {System.out.println("主线程开始");CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {int i = 1 / 0;System.out.println("加 10 任务开始");num += 10;return num;}).exceptionally(ex -> {//异常内容输出System.out.println(ex.getMessage());return -1;});System.out.println(future.get());}
private static Integer num = 10;public static void main(String[] args) throws Exception {System.out.println("主线程开始");CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {// int i= 1/0;System.out.println("加 10 任务开始");num += 10;return num;}).handle((i, ex) -> {System.out.println("进入 handle 方法");if (ex != null) {System.out.println("发生了异常,内容为:" + ex.getMessage());return -1;} else {System.out.println("正常完成,内容为: " + i);return i;}});System.out.println(future.get());}
private static Integer num = 10;public static void main(String[] args) throws Exception {System.out.println("主线程开始");//第一步加 10CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {System.out.println("加 10 任务开始");num += 10;return num;});//合并CompletableFuture<Integer> future1 = future.thenCompose(i ->//再来一个 CompletableFutureCompletableFuture.supplyAsync(() -> {return i + 1;}));System.out.println(future.get());System.out.println(future1.get());}
thenCombine 合并两个没有依赖关系的 CompletableFutures 任务
private static Integer num = 10;public static void main(String[] args) throws Exception {System.out.println("主线程开始");CompletableFuture<Integer> job1 = CompletableFuture.supplyAsync(() -> {System.out.println("加 10 任务开始");num += 10;return num;});CompletableFuture<Integer> job2 = CompletableFuture.supplyAsync(() -> {System.out.println("乘以 10 任务开始");num = num * 10;return num;});//合并两个结果CompletableFuture<Object> future = job1.thenCombine(job2, newBiFunction<Integer, Integer, List<Integer>>() {@Overridepublic List<Integer> apply(Integer a, Integer b) {List<Integer> list = new ArrayList<>();list.add(a);list.add(b);return list;}});System.out.println("合并结果为:" + future.get());}
private static Integer num = 10;/*** 先对一个数加 10,然后取平方* @param args*/public static void main(String[] args) throws Exception{System.out.println("主线程开始");List<CompletableFuture> list = new ArrayList<>();CompletableFuture<Integer> job1 = CompletableFuture.supplyAsync(() -> {System.out.println("加 10 任务开始");num += 10;return num;});list.add(job1);CompletableFuture<Integer> job2 = CompletableFuture.supplyAsync(() -> {System.out.println("乘以 10 任务开始");num = num * 10;return num;});list.add(job2);CompletableFuture<Integer> job3 = CompletableFuture.supplyAsync(() -> {System.out.println("减以 10 任务开始");num = num - 10;return num;});list.add(job3);CompletableFuture<Integer> job4 = CompletableFuture.supplyAsync(() -> {System.out.println("除以 10 任务开始");num = num / 10;return num;});list.add(job4);//多任务合并List<Integer> collect =list.stream().map(CompletableFuture<Integer>::join).collect(Collectors.toList());System.out.println(collect);}
private static Integer num = 10;/*** 先对一个数加 10,然后取平方* @param args*/public static void main(String[] args) throws Exception{System.out.println("主线程开始");List<CompletableFuture> list = new ArrayList<>();CompletableFuture<Integer> job1 = CompletableFuture.supplyAsync(() -> {System.out.println("加 10 任务开始");num += 10;return num;});list.add(job1);CompletableFuture<Integer> job2 = CompletableFuture.supplyAsync(() -> {System.out.println("乘以 10 任务开始");num = num * 10;return num;});list.add(job2);CompletableFuture<Integer> job3 = CompletableFuture.supplyAsync(() -> {System.out.println("减以 10 任务开始");num = num - 10;return num;});list.add(job3);CompletableFuture<Integer> job4 = CompletableFuture.supplyAsync(() -> {System.out.println("除以 10 任务开始");num = num / 10;return num;});list.add(job4);CompletableFuture<Void> future = CompletableFuture.allOf(job1, job2, job3, job4).whenComplete((a, b) -> {// b为异常对象if (b != null) {System.out.println("error stack trace->");b.printStackTrace();} else {System.out.println("run succ,result->" + a);}});System.out.println(future.get());}
private static Integer num = 10;/*** 先对一个数加 10,然后取平方** @param args*/public static void main(String[] args) throws Exception {System.out.println("主线程开始");CompletableFuture<Integer>[] futures = new CompletableFuture[4];CompletableFuture<Integer> job1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(5000);System.out.println("加 10 任务开始");num += 10;return num;} catch (Exception e) {return 0;}});futures[0] = job1;CompletableFuture<Integer> job2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);System.out.println("乘以 10 任务开始");num = num * 10;return num;} catch (Exception e) {return 1;}});futures[1] = job2;CompletableFuture<Integer> job3 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(3000);System.out.println("减以 10 任务开始");num = num - 10;return num;} catch (Exception e) {return 2;}});futures[2] = job3;CompletableFuture<Integer> job4 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(4000);System.out.println("除以 10 任务开始");num = num / 10;return num;} catch (Exception e) {return 3;}});futures[3] = job4;CompletableFuture future = CompletableFuture.anyOf(futures);System.out.println(future.get());}
①. 获得结果和触发计算(get、getNow、join、complete)
getNow ()方法 如果计算完成 返回计算完成后的结果 如果调用时没有完成 则返回一个指定的替代值
重点 join 与get 区别
join方法和get( )方法作用一样,不同的是,join方法不抛出异常
这些不予操作演示
②. 对计算结果进行处理(thenApply、handle) 将线程串行化
①. public <U> CompletableFuture<U> thenApply
计算结果存在依赖关系,这两个线程串行化
由于存在依赖关系(当前步错,不走下一步),当前步骤有异常的话就叫停
②. public <U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn):
有异常也可以往下一步走,根据带的异常参数可以进一步处理
③. whenComplete:是执行当前任务的线程执行继续执行whenComplete的任务
④. whenCompleteAsync:是执行把whenCompleteAsync这个任务继续提交给线程池来进行执行
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace();}return 1;}).thenApply(s->{// 这个s 是指上一步的返回值System.out.println("-----1");//如果加上int error=1/0; 由于存在依赖关系(当前步错,不走下一步),当前步骤有异常的话就叫 停//int error=1/0;return s+1;}).thenApply(s->{System.out.println("-----2");return s+2;}).whenComplete((v,e)->{// v 是指 异步操作数据的返回值 e指上面操作是否出现异常if(e==null){System.out.println("result-----"+v);}}).exceptionally(e->{e.printStackTrace();return null;});System.out.println(Thread.currentThread().getName()+"\t"+"over....");try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {e.printStackTrace();}
handle()与thenApply 效果相同 但是 thenApply 出现异常,线程立即停止 而handle 不会出现线程停止问题 会继续执行代码,同时也可以处理异常 等同于 thenApply() 和 exceptionally()结合
// 创建异步执行任务:CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(()->{return 1;}).thenApply((i)->{int q = 1/0;System.out.println("我被处以0了");return i+2;}).handle((i,e)->{if (e == null){return i +3;}else {e.printStackTrace();System.out.println("处理0");return 9;}});try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace();}System.out.println(cf.get());
③. 对计算结果进行消费(thenRun、thenAccept、thenApply)
①. thenRun(Runnable runnable)
任务A执行完执行B,并且B不需要A的结果 相当于另起一个线程
②. CompletableFuture<Void> thenAccept(Consumer<? super T> action)
任务A执行完成执行B,B需要A的结果,但是任务B 无返回值
③. public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
任务A执行完成执行B,B需要A的结果,同时任务B 有返回值
这些不予操作演示
某些方法 后缀 有Async 和没有 Async 后缀的方法的区别
带了Async的方法表示的是:会重新在线程池中启动一个线程来执行任务 这个线程池指的是CompletableFuture 创建时的默认线程池 即 ForkJoinPool.commonPool
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync
(Function<? super T,? extends U> fn, Executor executor)public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor)public CompletableFuture<Void> thenRun(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor)
④. 对计算速度进行选用(applyToEither、acceptEither、runAfterEither)
①. public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn)
这个方法表示的是,谁快就用谁的结果
applyToEither:两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值
acceptEither:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值
runAfterEither:两个任务有一个执行完成,不需要获取 future 的结果,处理任务,也没有返回值
applyToEither使用
CompletableFuture<String> playA = CompletableFuture.supplyAsync(() -> {System.out.println("A come in");try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }return "playA";});CompletableFuture<String> playB = CompletableFuture.supplyAsync(() -> {System.out.println("B come in");try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }return "playB";});CompletableFuture<String> result = playA.applyToEither(playB, f -> {return f + " is winer";});System.out.println(Thread.currentThread().getName()+"\t"+"-----: "+result.join());
---------------------------------------------------------------------------------------------------------------------------
System.out.println(CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {e.printStackTrace();}return 1;}).applyToEither(CompletableFuture.supplyAsync(() -> {try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace();}return 2;}), r -> {return r;}).join());
runAfterEither 使用
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return 1;});CompletableFuture<Integer> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return 2;});CompletableFuture<Void> voidCompletableFuture = integerCompletableFuture.runAfterEither(integerCompletableFuture2, () -> System.out.println(integerCompletableFuture2.join()));System.out.println(voidCompletableFuture.join());
带了Async的方法表示的是:会重新在线程池中启动一个线程来执行任务 这个线程池指的是CompletableFuture 创建时的默认线程池 即 ForkJoinPool.commonPool
public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn)
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn)
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn,Executor executor)public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action)
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action,Executor executor)public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,Runnable action)public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action) public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action,Executor executor)
⑤. 对计算结果进行合并(thenCombine、thenAcceptBoth、runAfterBoth)
①. public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn)
两个CompletionStage任务都完成后,最终把两个任务的结果一起交给thenCombine来处理
先完成的先等着,等待其他分支任务
thenCombine 使用
有返回值
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return 1;});CompletableFuture<Integer> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return 2;});CompletableFuture<Integer> future = integerCompletableFuture.thenCombine(integerCompletableFuture2, (a, b) -> a + b);System.out.println(future.join());
------------------------------------------------ 简化-------------------------------------
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() ->2).thenCombine(CompletableFuture.supplyAsync(() ->1),(a, b) ->a+b);System.out.println(future.join());
thenAcceptBoth 使用 无返回值
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return 1;});CompletableFuture<Integer> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return 2;});CompletableFuture<Void> voidCompletableFuture1 = integerCompletableFuture.thenAcceptBoth(integerCompletableFuture2, (a, b) -> System.out.println(a + b));
------------------------------------------------------ 简化-----------------------------------------------------
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.supplyAsync(() -> 1).thenAcceptBoth(CompletableFuture.supplyAsync(() -> 2), (a, b) -> System.out.println(a + b));System.out.println(voidCompletableFuture.join());
runAfterBoth 使用 无返回值
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return 1;});CompletableFuture<Integer> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return 2;});CompletableFuture<Void> voidCompletableFuture1 = integerCompletableFuture.runAfterBoth(integerCompletableFuture2, () -> System.out.println(integerCompletableFuture.join()+integerCompletableFuture2.join()));
----------------------------------------- 简化 ---------------------------------------------
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.supplyAsync(() -> 1).runAfterBoth(CompletableFuture.supplyAsync(() -> 2),()-> System.out.println()) ;
thenCompose 合并两个有依赖关系的 CompletableFutures 的执行结果
thenCompose方法会在某个任务执行完成后,将该任务的执行结果作为方法入参然后执行指定的方法,该方法会返回一个新的CompletableFuture实例,如果该CompletableFuture实例的result不为null,则返回一个基于该result的新的CompletableFuture实例;如果该CompletableFuture实例为null,则,然后执行这个新任务,测试用例如下:
CompletableFuture<Integer> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return 2;});CompletableFuture<Integer> future= integerCompletableFuture2.thenCompose(param->{System.out.println(param);return CompletableFuture.supplyAsync(()-> param+ 2);});System.out.println( future.join());
--------- 简化 -----------------------------------
CompletableFuture.supplyAsync(() ->2).thenCompose(param ->{return CompletableFuture.supplyAsync(()-> param+ 2);});
⑥. 多任务组合(allOf、anyOf)
①. allOf:等待所有任务完成
(public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs))
②. anyOf:只要有一个任务完成
(public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs))
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {System.out.println("查询商品的图片信息");return "hello.jpg";});CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {System.out.println("查询商品的属性");return "黑色+256G";});CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {e.printStackTrace();}System.out.println("查询商品介绍");return "华为";});//需要全部完成
// futureImg.get();
// futureAttr.get();
// futureDesc.get();//CompletableFuture<Void> all = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);//all.get();CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);anyOf.get();System.out.println(anyOf.get());System.out.println("main over.....");
同步与异步参考博客
同步与异步的区别(一看则懂)_小柠檬爱编程的博客-CSDN博客_同步异步的区别
Java面试题之:同步与异步?进程与线程?并发与并行?_faramita_of_mine的博客-CSDN博客_同步异步面试题
Java之阻塞和非阻塞以及同步和异步的区别_笑看风云路的博客-CSDN博客_java 异步阻塞
java 同步和异步_Java中的同步与异步详细介绍_时光派的博客-CSDN博客
Java --- 线程同步和异步的区别_怪伽先森的博客-CSDN博客_java线程同步和异步的区别
CompletableFuture 用法参考博客
JUC高并发编程从入门到精通(全)_码农研究僧的博客-CSDN博客_juc并发编程
Juc09_CompletableFuture概述、创建方式、常用API、电商比价需求_所得皆惊喜的博客-CSDN博客_completablefuture.allof
Java8 CompletableFuture 用法全解_孙大圣666的博客-CSDN博客_completablefuture
CompletableFuture详解~allOf_gqltt的博客-CSDN博客_completablefuture.allof
Java8 CompletableFuture(7) CompletableFuture allOf 获取所有线程结果_亚 瑟的博客-CSDN博客_completablefuture.allof
java 异步编程 CompletableFuture相关推荐
- 阿里技术专家加多:Java异步编程实战之基于JDK中的Future实现异步编程 | 文末赠书...
正文共:14244 字 8 图 预计阅读时间: 36 分钟 本节内容摘自<Java异步编程实战>中的一小节. 一.前言 本节主要讲解如何使用JDK中的Future实现异步编程,这包含如何使 ...
- Java 异步编程:从 Future 到 Loom
众所周知,Java 开始方法执行到结束,都是由同一个线程完成的.这种方式虽易于开发调试,但容易因为锁.IO 等原因导致线程挂起,产生线程上下文切换.随着对应用并发能力要求越来越高,频繁的线程上下文切换 ...
- 认识Java异步编程
一 .认识异步编程 通常Java开发人员喜欢使用同步代码编写程序,因为这种请求(request)/响应(response)的方式比较简单,并且比较符合编程人员的思维习惯;这种做法很好,直到系统出现性能 ...
- 阿里技术专家加多:Java异步编程实战之基于JDK中的Future实现异步编程
正文共:14244 字 8 图 预计阅读时间: 36 分钟 本节内容摘自<Java异步编程实战>中的一小节. 一.前言 本节主要讲解如何使用JDK中的Future实现异步编程,这包含如何使 ...
- java 异步_浅谈Java异步编程
本文来自网易云社区. Java异步编程引言 Java的异步编程其实是一个充分利用计算机CPU资源,不想让主程序阻塞在某个长时间运行的任务上,这类耗时的任务可以是IO操作.远程调用以及高密度计算任务.如 ...
- 《Java8实战》读书笔记10:组合式异步编程 CompletableFuture
<Java8实战>读书笔记10:组合式异步编程 CompletableFuture 第11章 CompletableFuture:组合式异步编程 11.1 Future 接口 (只是个引子 ...
- Java 异步编程 (5 种异步实现方式详解)
同步操作如果遇到一个耗时的方法,需要阻塞等待,那么我们有没有办法解决呢?让它异步执行,下面我会详解异步及实现 @mikechen 目录 什么是异步? 一.线程异步 二.Future异步 三.Compl ...
- 淘宝资深java技术专家整理分享java异步编程实战文档
前言 本文由淘宝资深java技术专家爆肝整理分享的java异步编程实战文档,针对常见异步编程场景,从编程语言.开发框架等角度深入讲解异步编程的原理和方法,每个技术点都附有案例代码! 通常Java开发人 ...
- 超赞!阿里资深P9架构师总结出第一本《Java异步编程实战》
什么是异步编程: 传统的同步编程是一种请求响应模型,调用一个方法,等待其响应返回 异步编程就是要重新考虑是否需要响应的问题,也就是缩小需要响应的地方.因为越快获得响应,就是越同步化,顺序化,事务化,性 ...
- Java中如何使用非阻塞异步编程——CompletableFuture
分享一波:程序员赚外快-必看的巅峰干货 对于Node开发者来说,非阻塞异步编程是他们引以为傲的地方.而在JDK8中,也引入了非阻塞异步编程的概念.所谓非阻塞异步编程,就是一种不需要等待返回结果的多线程 ...
最新文章
- crontab安装_django-crontab实现服务端的定时计划任务
- desktop docker 无法卸载_Docker容器无法停止或移除-权限被拒绝错误
- 提到刺这种兵器的guandan
- 在打字稿中,是什么! (惊叹号/ bang)运算符取消引用成员时?
- 容器技术Docker K8s 7 容器服务ACK集群
- html可视区高度,你真的懂js获取可视区宽高吗
- 证券交易1-交易系统简介
- 创业者必备知识SWOT分析模型+案例分析
- 解决fences2.01在win8.1的状态下无法移动桌面图标问题
- 如何在Web页面里使用高拍仪扫描上传图像
- 启动优化之一——启动分析及优化方案
- myChat - 第三方ChatGPT原生客户端,支持win和mac系统
- 8-2 sdust-Java-文件读取与统计【人工判编程题】 (30 分)
- 基于深度学习的三维重建算法综述
- Flutter——Flutter初探与Dart基础
- Linux平台上DPDK入门指南(二)
- 服务器维修故障诊断思路大全
- sqlserver 查询记录数 查系统表秒出
- 2022年全球市场数字电位器IC总体规模、主要生产商、主要地区、产品和应用细分研究报告
- 数独(日语:数独/すうどく sūdoku)