CompletableFuture的静态方法使用

1 completablefuture的静态方法使用completeablefuture的静态方法有如下
之前的文章里面已经讲过suuplyasync,以及runasync。我们就直接看其他方法
delayedexcutordelayedexcutor其作用是构建一个延迟执行任务的excutor,默认使用forkjoinpool. 也可以使用自定义的excutor。
一个延迟5秒执行任务的excutor,默认使用使用forkjoinpool.commonpool()。executor executor = completablefuture.delayedexecutor(5l, timeunit.seconds);allof和anyofallof和anyof 为等待多个completablefuture完成之后返回一个completablefuture。
allof返回无result,anyof返回为最先完成的completablefuture。可以看如下示例。
completablefuture supplyasync1 = completablefuture.supplyasync(()- >{ try {thread.sleep(4 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return supplyasync1;});completablefuture supplyasync2 = completablefuture.supplyasync(() - > { try {thread.sleep(2 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return supplyasync2;});completablefuture.anyof(supplyasync1,supplyasync2).thenaccept((str)- >{ system.out.println(localdatetime.now() + anyof complete : + str);});completablefuture.allof(supplyasync1,supplyasync2).thenaccept((str)- >{ system.out.println(localdatetime.now() + allof complete + str );});执行结果如下:
start second: 2021-10-24t12:39:40.5620016002021-10-24t12:39:42.611118800 anyof complete : supplyasync22021-10-24t12:39:44.611233200 allof complete nullfailedstage和failedfuture是返回一个已知异常的completablefuture。这个下面和其他异常一起举例。
2 completablefuture的其余方法使用completablefuture中方法可以大致分为run,apply,accept几个类别。其对应的参数分别为runnable,function,consummer等几个函数式表达式。
run代表当前completablefuture完成后执行的一些列操作,无输入参数,无返回结果,所以只是runnable为参数。()-> { option }apply代表以当前completablefuture完成后的结果为参数进行的操作,并且会返回一个新的completablefuture,所以以function为参数。(s)-> {return s;}accept代表以当前completablefuture完成后的结果为参数,执行的操作,无返回结果,直接消费。以consumer为参数,(s)-> { option }。2.1 run方法run方法相关参数为runnable,为直接执行的操作。
thenrun 完成之后直接执行。
thenrunasync 使用线程池异步执行,线程池默认为forkjoinpool.commonpool
runafterboth/ runaftereither 两个completablefuture同时完成或者某一个完成就执行的操作。
runafterbothasync/runaftereitherasync 同理为使用线程池异步执行的操作。
public class completablefuturethenrun { public static void main(string[] args) { system.out.println( completablefuturethenrun main start : + localdatetime.now()); completablefuture cf1 = completablefuture.supplyasync(() - > { system.out.println( completablefuturethenrun cf1: + localdatetime.now()); try { thread.sleep(5 * 1000); } catch (interruptedexception e) { e.printstacktrace(); } return supplyasync; }); completablefuture cf2 = completablefuture.runasync(() - > { system.out.println( completablefuturethenrun cf2: + localdatetime.now()); try { thread.sleep(2 * 1000); } catch (interruptedexception e) { e.printstacktrace(); } }); cf1.runafterboth(cf2,()- > { system.out.println(thread.currentthread().getname()+ completablefuturethenrun runafterboth: + localdatetime.now()); }); cf1.runafterbothasync(cf2,()- > { system.out.println( thread.currentthread().getname()+ completablefuturethenrun runafterbothasync: + localdatetime.now()); }); cf1.runaftereither(cf2,()- > { system.out.println( thread.currentthread().getname()+ completablefuturethenrun runaftereither: + localdatetime.now()); }); cf1.runaftereitherasync(cf2,()- > { system.out.println( thread.currentthread().getname()+ completablefuturethenrun runaftereitherasync: + localdatetime.now()); }); cf1.thenrunasync(()- > { system.out.println(thread.currentthread().getname()+ completablefuturethenrun thenrunasync: + localdatetime.now()); }); cf1.thenrun(()- > { system.out.println(thread.currentthread().getname()+ completablefuturethenrun thenrun: + localdatetime.now()); }); system.out.println(thread.currentthread().getname() + completablefuturethenrun last: + localdatetime.now()); try { thread.sleep(10*1000); } catch (interruptedexception e) { e.printstacktrace(); } }}上述执行结果:
completablefuturethenrun main start : 2021-10-25t01:48:52.416000900 completablefuturethenrun cf1: 2021-10-25t01:48:52.492008500 completablefuturethenrun cf2: 2021-10-25t01:48:52.493008600main completablefuturethenrun last: 2021-10-25t01:48:52.495008800forkjoinpool.commonpool-worker-7 completablefuturethenrun runaftereitherasync: 2021-10-25t01:48:54.495208800forkjoinpool.commonpool-worker-3 completablefuturethenrun runaftereither: 2021-10-25t01:48:54.495208800forkjoinpool.commonpool-worker-5 completablefuturethenrun thenrun: 2021-10-25t01:48:57.493508600forkjoinpool.commonpool-worker-3 completablefuturethenrun thenrunasync: 2021-10-25t01:48:57.494508700forkjoinpool.commonpool-worker-3 completablefuturethenrun runafterboth: 2021-10-25t01:48:57.494508700forkjoinpool.commonpool-worker-3 completablefuturethenrun runafterbothasync: 2021-10-25t01:48:57.495508800apply 与accept相关的方法类似,此处不一一举例了。
下面我们根据一些情景举例来说明方法如何使用:
2.2 多个 completablefuture组合在一起执行情景一 :先去取快递,然后再去买菜,然后回家做饭。
completablefuture cf = completablefuture.supplyasync(()- >{ system.out.println(localdatetime.now() + 正在取快递! ); try {thread.sleep(2 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return 快递1;}).thenapply((str) - > { system.out.println(localdatetime.now() + 拿到了: +str); system.out.println(localdatetime.now() + 买菜中。。。 ); try {thread.sleep(2 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return str + 和 蔬菜;}).thenapply((str2)- >{ system.out.println(localdatetime.now() + 现在有了: [+str2+]); try {thread.sleep(2 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return 带着 [ + str2 + ]回家做饭 ;});system.out.println( localdatetime.now() + 美好的一天: + cf.join());下面看一下上面的执行结果,
2021-10-25t01:10:16.831465600 正在取快递! 2021-10-25t01:10:18.861668600 拿到了: 快递12021-10-25t01:10:18.911673600 买菜中。。。 2021-10-25t01:10:20.911873600 现在有了: [快递1 和 蔬菜]2021-10-25t01:10:16.831465600 美好的一天: 带着 [快递1 和 蔬菜 ]回家做饭可以看到最后一行输出的时间比较早,这是因为join会阻塞线程,直到此completablefuture执行完并获取到值。
情景二 :和女朋友一起出门,我去取快递,女朋友去买菜,然后一起回家做饭。
completablefuture cf1 = completablefuture.supplyasync(()- >{ system.out.println(localdatetime.now() + 正在取快递! ); try {thread.sleep(2 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return 快递;});completablefuture cf2 = completablefuture.supplyasync(()- >{ system.out.println(localdatetime.now() + 女朋友正在买菜! ); try {thread.sleep(4 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return 蔬菜;});cf1.thenacceptboth(cf2,(str1 ,str2 )- >{ system.out.println(localdatetime.now() + [+ str1 + ][+str2+] 带回来了,开始做饭 );}).join();此处使用 thenacceptboth 需要在两个completablefuture都完成的情况下,才能执行,所以最后使用join()使其阻塞到可以执行当前的操作。
情景三 :和女朋友一起出门,我去取快递,女朋友去买菜,谁先弄完谁就先回去。
cf1.accepteither(cf2,(str1 )- >{ system.out.println(localdatetime.now() + [+ str1 +] 带回来了,先回家吧! );}).join();我先拿到了快递,就快快的回家了,然后就挨了一顿毒打。
2.3 在两个completablefuture运行后再次计算晚饭过后和女朋友讨论做什么事情,然而发生了分歧:
completablefuture cf1 = completablefuture.supplyasync(()- >{ list strings = arrays.aslist(看电影, 打扑克); system.out.println(localdatetime.now() + 晚饭后女朋友说,想要: + strings); try {thread.sleep(2 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return strings;});completablefuture cf2 = completablefuture.supplyasync(()- >{ list strings = arrays.aslist(看电影, 打游戏); system.out.println(localdatetime.now() + 晚饭后,我想: + strings); try {thread.sleep(4 * 1000);} catch (interruptedexception e) {e.printstacktrace();} return strings;});cf1.thencombine(cf2,(list1,list2) - > { system.out.println(遭受了一顿毒打之后。。。!!!); list collect = list1.stream().filter(str - > list2.contains(str)).collect(collectors.tolist()); system.out.println(localdatetime.now() + 综合两个人的想法,最终决定: + collect); return collect;}).join();女朋友想看电影,或者打扑克,
但是我想打游戏。最后遭受一顿毒打之后,还是说出了或者看电影。
最终选择了看电影。
4 completablefuture的异常处理completablefuture和异常相关的方法有如下
4.1 whencomplete/whencompleteasynccompletablefuture whencomplete( biconsumer action)whencompletable使用有biconsumer里面会有两个参数,下边是一个示例。参数需要两个分别为str,exception, 如果有异常exception有值,str为null。如果stringcompletablefuture正常完成,则exception为null。但是不管是否有异常,表达式里面的方法均会执行。
有点类似try finally{},有没有异常均可执行。
completablefuture whencompletecf = stringcompletablefuture.whencomplete((str, exception) - > { if(exception != null){ system.out.println(whencomplete : + exception); exception.printstacktrace(); } system.out.println(whencomplete execute whither error throw );});4.2 exceptionallyexceptionally方法中为一个function参数,需要一个输入值,为当前completablefuture抛出的异常。
其返回值有两个结果:
如果当前completablefuture无异常完成,则返回与原completablefuture的result相同的completablefuture,注意知识result相同,并不是同一个类。如果当前completablefuture有异常抛出,那么返回新的completablefuture以及新处理后的result。completablefuture stringcompletablefuture = completablefuture.supplyasync(() - > { throw new runtimeexception( completablefuture throw one exception);// return cc; }); completablefuture exceptionally = stringcompletablefuture.exceptionally((exception) - > { system.out.println(exceptionally only execute when error throw ); return exception; }); system.out.println(exceptionally : + exceptionally.join());上述示例无异常抛出时结果如下:
exceptionally :cc有异常抛出时结果如下:
exceptionally only execute when error throw exceptionally :exception4.3 handle/handleasyncpublic completablefuture handle( bifunction fn)handle 和 whencomplete 比较类似,无论有没有异常,里面的方法均会执行到。
但是有有一些区别,handle参数为bifunction,有返回值,whencomplet的参数为bicomsumer 无返回值。
下面的实例中,如果有异常则参数中的str为null,如果没有异常exception为null。
completablefuture handle = stringcompletablefuture.handle((str, exception) - > { system.out.println(handle : + str); if(exception != null ){ system.out.println(stringcompletablefuture1 have exception : ); exception.printstacktrace(); } return handle complete ;});有异常的执行结果:
stringcompletablefuture1 have exception :handle.join(); :handle complete无异常的执行结果
handle :cchandle.join(); :handle complete4.4 failedstage/failedfuturefailedstage和failedfuture均为静态方法,会返回一个已完成的给定异常的completablefuture。
failedstage返回的是completionstage,failedfuture返回为completablefuture对象
completionstage test_exception = completablefuture.failedstage(new runtimeexception(test exception));completablefuture test_exception1 = completablefuture.failedfuture(new runtimeexception(test exception));最后给一个可以直接食用的示例,可以根据不同的需求进行改良哦!
public static map testmap = new concurrenthashmap();static { testmap.put(a, arrays.aslist(1,2,3,4,5)); testmap.put(b, arrays.aslist(6,7,8,9,10)); testmap.put(c, arrays.aslist(11,12,13,14,15)); testmap.put(d, arrays.aslist(21,22,23,24,25)); testmap.put(e, arrays.aslist(31,32,33,34,35));}public static void main(string[] args) { system.out.println( completablefuturedemo5 main start : + localdatetime.now()); list strings = arrays.aslist(a, b, c, d, e); executorservice testpool = new forkjoinpool(4); list< completablefuture > collect = strings.stream().map( key - > completablefuture.supplyasync(() - > { return obtainthelist(key); },testpool).exceptionally((exc)- >{ system.out.println( hit the exception ); throw new runtimeexception(exc); }) ).collect(collectors.tolist()); system.out.println( completablefuturedemo5 supplyasync end : + localdatetime.now()); try { list integercollect = collect.stream().map(completablefuture::join).collect(collectors.tolist()); }catch (exception e){ system.out.println( catch the exception + e.getmessage()); e.printstacktrace(); } system.out.println( completablefuturedemo5 main end : + localdatetime.now()); try { thread.sleep(5*1000); } catch (interruptedexception e) { e.printstacktrace(); }}private static list obtainthelist(string key) { list integers = testmap.get(key); if( key.equals(c) ){ throw new runtimeexception(exception test !); } try { thread.sleep(2*1000); system.out.println( obtainthelist thread name : + thread.currentthread().getname() + : + localdatetime.now()); } catch (interruptedexception e) { e.printstacktrace(); } return integers==null? new arraylist() :integers;}总结本片用了一些示例来讲解completablefuture,我们可以在开发中的一些场景中使用起来了。特别是异步多线程去拿一些数据的时候,非常好用哦。

工业物联网和消费物联网两者之间有什么区别?
Leap Motion展示北极星AR头显首款演示demo
肉类水分快速检测仪让注水肉快速现身
B100_A核心板-高性能AI智能模块参数特性概述
判断PLC是真坏了还是假损坏的步骤
CompletableFuture的静态方法使用
传感器设备开发不止步于可穿戴设备
医疗器械的基础知识分享
想要解决无线路由器的信号问题 就要选择最适合自己的组网方案
RA6M3修复ra_pin_mode、rt_ssize_t ra_uart_transmit文件类型错误
天跃科技TY-SIMS安防智能管理系统的功能实现和应用设计
CD4026数字钟电路
海克斯康与成都航空职业技术学院展开制造智能二度合作
5nm、7nm工艺订单暴增,台积电营收创新高
反相运算放大器基础知识讲解
DBL2044波段切换芯片各引脚功能及电压
交直流两用功放电路制作
无人机+人工智能+云协作可缩短飞机检查时间
ST在MICROTech World上展示MEMS技术多项应用成果
马可尼-实用无线电报通信创始人