0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

異步神器CompletableFuture萬字詳解!

jf_ro2CN3Fa ? 來源:CSDN ? 作者:CSDN ? 2022-11-15 10:15 ? 次閱讀


CompletableFuture是jdk8的新特性。CompletableFuture實(shí)現(xiàn)了CompletionStage接口和Future接口,前者是對(duì)后者的一個(gè)擴(kuò)展,增加了異步會(huì)點(diǎn)、流式處理、多個(gè)Future組合處理的能力,使Java在處理多任務(wù)的協(xié)同工作時(shí)更加順暢便利。

一、創(chuàng)建異步任務(wù)

1. supplyAsync

supplyAsync是創(chuàng)建帶有返回值的異步任務(wù)。它有如下兩個(gè)方法,一個(gè)是使用默認(rèn)線程池(ForkJoinPool.commonPool())的方法,一個(gè)是帶有自定義線程池的重載方法

//帶返回值異步請(qǐng)求,默認(rèn)線程池
publicstaticCompletableFuturesupplyAsync(Suppliersupplier)

//帶返回值的異步請(qǐng)求,可以自定義線程池
publicstaticCompletableFuturesupplyAsync(Suppliersupplier,Executorexecutor)

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf=CompletableFuture.supplyAsync(()->{
System.out.println("dosomething....");
return"result";
});

//等待任務(wù)執(zhí)行完成
System.out.println("結(jié)果->"+cf.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
//自定義線程池
ExecutorServiceexecutorService=Executors.newSingleThreadExecutor();
CompletableFuturecf=CompletableFuture.supplyAsync(()->{
System.out.println("dosomething....");
return"result";
},executorService);

//等待子任務(wù)執(zhí)行完成
System.out.println("結(jié)果->"+cf.get());
}

測(cè)試結(jié)果:

90bc4a4e-648a-11ed-8abf-dac502259ad0.png

2. runAsync

runAsync是創(chuàng)建沒有返回值的異步任務(wù)。它有如下兩個(gè)方法,一個(gè)是使用默認(rèn)線程池(ForkJoinPool.commonPool())的方法,一個(gè)是帶有自定義線程池的重載方法

//不帶返回值的異步請(qǐng)求,默認(rèn)線程池
publicstaticCompletableFuturerunAsync(Runnablerunnable)

//不帶返回值的異步請(qǐng)求,可以自定義線程池
publicstaticCompletableFuturerunAsync(Runnablerunnable,Executorexecutor)

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf=CompletableFuture.runAsync(()->{
System.out.println("dosomething....");
});

//等待任務(wù)執(zhí)行完成
System.out.println("結(jié)果->"+cf.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
//自定義線程池
ExecutorServiceexecutorService=Executors.newSingleThreadExecutor();
CompletableFuturecf=CompletableFuture.runAsync(()->{
System.out.println("dosomething....");
},executorService);

//等待任務(wù)執(zhí)行完成
System.out.println("結(jié)果->"+cf.get());
}

測(cè)試結(jié)果:

90e0da4e-648a-11ed-8abf-dac502259ad0.png

3.獲取任務(wù)結(jié)果的方法

//如果完成則返回結(jié)果,否則就拋出具體的異常
publicTget()throwsInterruptedException,ExecutionException

//最大時(shí)間等待返回結(jié)果,否則就拋出具體異常
publicTget(longtimeout,TimeUnitunit)throwsInterruptedException,ExecutionException,TimeoutException

//完成時(shí)返回結(jié)果值,否則拋出unchecked異常。為了更好地符合通用函數(shù)形式的使用,如果完成此CompletableFuture所涉及的計(jì)算引發(fā)異常,則此方法將引發(fā)unchecked異常并將底層異常作為其原因
publicTjoin()

//如果完成則返回結(jié)果值(或拋出任何遇到的異常),否則返回給定的valueIfAbsent。
publicTgetNow(TvalueIfAbsent)

//如果任務(wù)沒有完成,返回的值設(shè)置為給定值
publicbooleancomplete(Tvalue)

//如果任務(wù)沒有完成,就拋出給定異常
publicbooleancompleteExceptionally(Throwableex)

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

二、異步回調(diào)處理

1. thenApply和thenApplyAsync

thenApply 表示某個(gè)任務(wù)執(zhí)行完成后執(zhí)行的動(dòng)作,即回調(diào)方法,會(huì)將該任務(wù)的執(zhí)行結(jié)果即方法返回值作為入?yún)鬟f到回調(diào)方法中,帶有返回值。

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenApplyAsync((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
result+=2;
returnresult;
});
//等待任務(wù)1執(zhí)行完成
System.out.println("cf1結(jié)果->"+cf1.get());
//等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenApply((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
result+=2;
returnresult;
});
//等待任務(wù)1執(zhí)行完成
System.out.println("cf1結(jié)果->"+cf1.get());
//等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}

測(cè)試結(jié)果:

9114db50-648a-11ed-8abf-dac502259ad0.png 914c3bd6-648a-11ed-8abf-dac502259ad0.png

從上面代碼和測(cè)試結(jié)果我們發(fā)現(xiàn)thenApply和thenApplyAsync區(qū)別在于,使用thenApply方法時(shí)子任務(wù)與父任務(wù)使用的是同一個(gè)線程,而thenApplyAsync在子任務(wù)中是另起一個(gè)線程執(zhí)行任務(wù),并且thenApplyAsync可以自定義線程池,默認(rèn)的使用ForkJoinPool.commonPool()線程池。

2. thenAccept和thenAcceptAsync

thenAccep表示某個(gè)任務(wù)執(zhí)行完成后執(zhí)行的動(dòng)作,即回調(diào)方法,會(huì)將該任務(wù)的執(zhí)行結(jié)果即方法返回值作為入?yún)鬟f到回調(diào)方法中,無返回值。

測(cè)試代碼

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenAccept((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任務(wù)1執(zhí)行完成
System.out.println("cf1結(jié)果->"+cf1.get());
//等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenAcceptAsync((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任務(wù)1執(zhí)行完成
System.out.println("cf1結(jié)果->"+cf1.get());
//等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}

測(cè)試結(jié)果:

915c4ad0-648a-11ed-8abf-dac502259ad0.png 917f8ce8-648a-11ed-8abf-dac502259ad0.png從上面代碼和測(cè)試結(jié)果我們發(fā)現(xiàn)thenAccep和thenAccepAsync區(qū)別在于,使用thenAccep方法時(shí)子任務(wù)與父任務(wù)使用的是同一個(gè)線程,而thenAccepAsync在子任務(wù)中可能是另起一個(gè)線程執(zhí)行任務(wù),并且thenAccepAsync可以自定義線程池,默認(rèn)的使用ForkJoinPool.commonPool()線程池。

3.thenRun和thenRunAsync

thenRun表示某個(gè)任務(wù)執(zhí)行完成后執(zhí)行的動(dòng)作,即回調(diào)方法,無入?yún)?,無返回值。

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenRun(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任務(wù)1執(zhí)行完成
System.out.println("cf1結(jié)果->"+cf1.get());
//等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenRunAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任務(wù)1執(zhí)行完成
System.out.println("cf1結(jié)果->"+cf1.get());
//等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}

測(cè)試結(jié)果:

919bd614-648a-11ed-8abf-dac502259ad0.png91aa1882-648a-11ed-8abf-dac502259ad0.png

從上面代碼和測(cè)試結(jié)果我們發(fā)現(xiàn)thenRun和thenRunAsync區(qū)別在于,使用thenRun方法時(shí)子任務(wù)與父任務(wù)使用的是同一個(gè)線程,而thenRunAsync在子任務(wù)中可能是另起一個(gè)線程執(zhí)行任務(wù),并且thenRunAsync可以自定義線程池,默認(rèn)的使用ForkJoinPool.commonPool()線程池。

4.whenComplete和whenCompleteAsync

whenComplete是當(dāng)某個(gè)任務(wù)執(zhí)行完成后執(zhí)行的回調(diào)方法,會(huì)將執(zhí)行結(jié)果或者執(zhí)行期間拋出的異常傳遞給回調(diào)方法,如果是正常執(zhí)行則異常為null,回調(diào)方法對(duì)應(yīng)的CompletableFuture的result和該任務(wù)一致,如果該任務(wù)正常執(zhí)行,則get方法返回執(zhí)行結(jié)果,如果是執(zhí)行異常,則get方法拋出異常。

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
inta=1/0;
return1;
});

CompletableFuturecf2=cf1.whenComplete((result,e)->{
System.out.println("上個(gè)任務(wù)結(jié)果:"+result);
System.out.println("上個(gè)任務(wù)拋出異常:"+e);
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

////等待任務(wù)1執(zhí)行完成
//System.out.println("cf1結(jié)果->"+cf1.get());
////等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}

測(cè)試結(jié)果:

91b85c44-648a-11ed-8abf-dac502259ad0.png

whenCompleteAsync和whenComplete區(qū)別也是whenCompleteAsync可能會(huì)另起一個(gè)線程執(zhí)行任務(wù),并且thenRunAsync可以自定義線程池,默認(rèn)的使用ForkJoinPool.commonPool()線程池。

5.handle和handleAsync

跟whenComplete基本一致,區(qū)別在于handle的回調(diào)方法有返回值。

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
//inta=1/0;
return1;
});

CompletableFuturecf2=cf1.handle((result,e)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
System.out.println("上個(gè)任務(wù)結(jié)果:"+result);
System.out.println("上個(gè)任務(wù)拋出異常:"+e);
returnresult+2;
});

//等待任務(wù)2執(zhí)行完成
System.out.println("cf2結(jié)果->"+cf2.get());
}

測(cè)試結(jié)果 :

91dba032-648a-11ed-8abf-dac502259ad0.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

三、多任務(wù)組合處理

1. thenCombine、thenAcceptBoth 和runAfterBoth

這三個(gè)方法都是將兩個(gè)CompletableFuture組合起來處理,只有兩個(gè)任務(wù)都正常完成時(shí),才進(jìn)行下階段任務(wù)。

區(qū)別:thenCombine會(huì)將兩個(gè)任務(wù)的執(zhí)行結(jié)果作為所提供函數(shù)的參數(shù),且該方法有返回值;thenAcceptBoth同樣將兩個(gè)任務(wù)的執(zhí)行結(jié)果作為方法入?yún)?,但是無返回值;runAfterBoth沒有入?yún)?,也沒有返回值。注意兩個(gè)任務(wù)中只要有一個(gè)執(zhí)行異常,則將該異常信息作為指定任務(wù)的執(zhí)行結(jié)果。

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
return2;
});

CompletableFuturecf3=cf1.thenCombine(cf2,(a,b)->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
returna+b;
});

System.out.println("cf3結(jié)果->"+cf3.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
return2;
});

CompletableFuturecf3=cf1.thenAcceptBoth(cf2,(a,b)->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
System.out.println(a+b);
});

System.out.println("cf3結(jié)果->"+cf3.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
return2;
});

CompletableFuturecf3=cf1.runAfterBoth(cf2,()->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
});

System.out.println("cf3結(jié)果->"+cf3.get());
}

測(cè)試結(jié)果:

91f51922-648a-11ed-8abf-dac502259ad0.png9211a330-648a-11ed-8abf-dac502259ad0.png

92274e9c-648a-11ed-8abf-dac502259ad0.png 2.applyToEither、acceptEither和runAfterEither

這三個(gè)方法和上面一樣也是將兩個(gè)CompletableFuture組合起來處理,當(dāng)有一個(gè)任務(wù)正常完成時(shí),就會(huì)進(jìn)行下階段任務(wù)。

區(qū)別:applyToEither會(huì)將已經(jīng)完成任務(wù)的執(zhí)行結(jié)果作為所提供函數(shù)的參數(shù),且該方法有返回值;acceptEither同樣將已經(jīng)完成任務(wù)的執(zhí)行結(jié)果作為方法入?yún)?,但是無返回值;runAfterEither沒有入?yún)?,也沒有返回值。

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf1任務(wù)完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf2任務(wù)完成";
});

CompletableFuturecf3=cf1.applyToEither(cf2,(result)->{
System.out.println("接收到"+result);
System.out.println(Thread.currentThread()+"cf3dosomething....");
return"cf3任務(wù)完成";
});

System.out.println("cf3結(jié)果->"+cf3.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf1任務(wù)完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf2任務(wù)完成";
});

CompletableFuturecf3=cf1.acceptEither(cf2,(result)->{
System.out.println("接收到"+result);
System.out.println(Thread.currentThread()+"cf3dosomething....");
});

System.out.println("cf3結(jié)果->"+cf3.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf1任務(wù)完成");
return"cf1任務(wù)完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf2任務(wù)完成");
return"cf2任務(wù)完成";
});

CompletableFuturecf3=cf1.runAfterEither(cf2,()->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
System.out.println("cf3任務(wù)完成");
});

System.out.println("cf3結(jié)果->"+cf3.get());
}

測(cè)試結(jié)果:

92418438-648a-11ed-8abf-dac502259ad0.png925d7cc4-648a-11ed-8abf-dac502259ad0.png

從上面可以看出cf1任務(wù)完成需要2秒,cf2任務(wù)完成需要5秒,使用applyToEither組合兩個(gè)任務(wù)時(shí),只要有其中一個(gè)任務(wù)完成時(shí),就會(huì)執(zhí)行cf3任務(wù),顯然cf1任務(wù)先完成了并且將自己任務(wù)的結(jié)果傳值給了cf3任務(wù),cf3任務(wù)中打印了接收到cf1任務(wù)完成,接著完成自己的任務(wù),并返回cf3任務(wù)完成;acceptEither和runAfterEither類似,acceptEither會(huì)將cf1任務(wù)的結(jié)果作為cf3任務(wù)的入?yún)?,但cf3任務(wù)完成時(shí)并無返回值;runAfterEither不會(huì)將cf1任務(wù)的結(jié)果作為cf3任務(wù)的入?yún)?,它是沒有任務(wù)入?yún)?,?zhí)行完自己的任務(wù)后也并無返回值。

2. allOf / anyOf

allOf:CompletableFuture是多個(gè)任務(wù)都執(zhí)行完成后才會(huì)執(zhí)行,只有有一個(gè)任務(wù)執(zhí)行異常,則返回的CompletableFuture執(zhí)行g(shù)et方法時(shí)會(huì)拋出異常,如果都是正常執(zhí)行,則get返回null。

anyOf :CompletableFuture是多個(gè)任務(wù)只要有一個(gè)任務(wù)執(zhí)行完成,則返回的CompletableFuture執(zhí)行g(shù)et方法時(shí)會(huì)拋出異常,如果都是正常執(zhí)行,則get返回執(zhí)行完成任務(wù)的結(jié)果。

測(cè)試代碼:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf1任務(wù)完成");
return"cf1任務(wù)完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
inta=1/0;
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf2任務(wù)完成");
return"cf2任務(wù)完成";
});

CompletableFuturecf3=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf3任務(wù)完成");
return"cf3任務(wù)完成";
});

CompletableFuturecfAll=CompletableFuture.allOf(cf1,cf2,cf3);
System.out.println("cfAll結(jié)果->"+cfAll.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf1任務(wù)完成");
return"cf1任務(wù)完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf2任務(wù)完成");
return"cf2任務(wù)完成";
});

CompletableFuturecf3=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf3任務(wù)完成");
return"cf3任務(wù)完成";
});

CompletableFuturecfAll=CompletableFuture.anyOf(cf1,cf2,cf3);
System.out.println("cfAll結(jié)果->"+cfAll.get());
}

		

測(cè)試結(jié)果:

9278b9a8-648a-11ed-8abf-dac502259ad0.png928fa848-648a-11ed-8abf-dac502259ad0.png

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8459

    瀏覽量

    150748
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    504

    瀏覽量

    19636

原文標(biāo)題:一網(wǎng)打盡:異步神器 CompletableFuture 萬字詳解!

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    第三篇-V1.5 TB6612電機(jī)pwm控制STM32智能小車 STM32F103C8T6單片機(jī)

    通過合理的硬件設(shè)計(jì)和詳細(xì)的視頻筆記介紹,硬件使用STM32F103主控資料多方便學(xué)習(xí),通過3萬字筆記、12多個(gè)小時(shí)視頻、20多章節(jié)代碼手把手教會(huì)你如何開發(fā)和調(diào)試。
    的頭像 發(fā)表于 08-12 18:29 ?1325次閱讀
    第三篇-V1.5 TB6612電機(jī)pwm控制STM32智能小車 STM32F103C8T6單片機(jī)

    第一篇:V1.5-STM32f103c8t6智能小車筆記 標(biāo)準(zhǔn)庫開發(fā) 6612電機(jī)驅(qū)動(dòng)新手入門項(xiàng)目

    這是全網(wǎng)最詳細(xì)、性價(jià)比最高的STM32實(shí)戰(zhàn)項(xiàng)目入門教程,通過合理的硬件設(shè)計(jì)和詳細(xì)的視頻筆記介紹,硬件使用STM32F103主控資料多方便學(xué)習(xí),通過3萬字筆記、12多個(gè)小時(shí)視頻、20多章節(jié)代碼手把手教會(huì)你如何開發(fā)和調(diào)試。讓你更快掌握嵌入式系統(tǒng)開發(fā)。
    的頭像 發(fā)表于 08-12 18:25 ?1457次閱讀
    第一篇:V1.5-STM32f103c8t6智能小車筆記 標(biāo)準(zhǔn)庫開發(fā) 6612電機(jī)驅(qū)動(dòng)新手入門項(xiàng)目

    Java CompletableFuture 異步超時(shí)實(shí)現(xiàn)探索

    簡(jiǎn)介 JDK 8 中 CompletableFuture 沒有超時(shí)中斷任務(wù)的能力?,F(xiàn)有做法強(qiáng)依賴任務(wù)自身的超時(shí)實(shí)現(xiàn)。本文提出一種異步超時(shí)實(shí)現(xiàn)方案,解決上述問題。 前言 JDK 8 是一次重大的版本
    的頭像 發(fā)表于 07-25 14:06 ?290次閱讀

    1.3萬字詳解半導(dǎo)體先進(jìn)封裝行業(yè),現(xiàn)狀及發(fā)展趨勢(shì)!

    共賞好劇 ? 導(dǎo) 讀?? 在以人工智能、高性能計(jì)算為代表的新需求驅(qū)動(dòng)下,先進(jìn)封裝應(yīng)運(yùn)而生,發(fā)展趨勢(shì)是小型化、高集成度,歷經(jīng)直插型封裝、表面貼裝、面積陣列封裝、2.5D/3D封裝和異構(gòu)集成四個(gè)發(fā)展階段。 典型封裝技術(shù)包括:1)倒片封裝(Flip-Chip):芯片倒置,舍棄金屬引線,利用凸塊連接;2)扇入型/扇出型封裝(Fan-In/Fan-Out):在晶圓上進(jìn)行整體封裝,成本更低,關(guān)鍵工藝為重新布線(RDL);3)2.5D/3D封裝:2.5D封裝中芯片位于硅中介層上,3D封裝舍
    的頭像 發(fā)表于 07-03 08:44 ?1542次閱讀
    1.3<b class='flag-5'>萬字</b>!<b class='flag-5'>詳解</b>半導(dǎo)體先進(jìn)封裝行業(yè),現(xiàn)狀及發(fā)展趨勢(shì)!

    萬字長(zhǎng)文淺談系統(tǒng)穩(wěn)定性建設(shè)

    流程:需求階段,研發(fā)階段,測(cè)試階段,上線階段,運(yùn)維階段;整個(gè)流程中的所有參與人員:產(chǎn)品,研發(fā),測(cè)試,運(yùn)維人員都應(yīng)關(guān)注系統(tǒng)的穩(wěn)定性。業(yè)務(wù)的發(fā)展及系統(tǒng)建設(shè)過程中,穩(wěn)定性就是那個(gè)1,其他的是1后面的0,沒有穩(wěn)定性,就好比將
    的頭像 發(fā)表于 07-02 10:31 ?325次閱讀
    <b class='flag-5'>萬字</b>長(zhǎng)文淺談系統(tǒng)穩(wěn)定性建設(shè)

    商湯大模型開“卷”長(zhǎng)文本,支持100萬字處理

    知情者透露,此次升級(jí)的日日新大模型還具備跨平臺(tái)操作特性,在Web和App端都可以使用。App端更是新增了粵語口語語音對(duì)話功能,進(jìn)一步提升了模型對(duì)粵語及香港本土文化的理解。
    的頭像 發(fā)表于 05-29 11:43 ?382次閱讀

    MiniMax推出“海螺AI”,支持超長(zhǎng)文本處理

    近日,大模型公司MiniMax宣布,其全新產(chǎn)品“海螺AI”已正式上架。這款強(qiáng)大的AI工具支持高達(dá)200ktokens的上下文長(zhǎng)度,能夠在1秒內(nèi)處理近3萬字的文本。
    的頭像 發(fā)表于 05-17 09:30 ?683次閱讀

    AI初創(chuàng)企業(yè)推MoE混合專家模型架構(gòu)新品abab 6.5

    losoev 6.5s:與 losoev 6.5 共享相同的訓(xùn)練技術(shù)和數(shù)據(jù),但效率更高,同樣支持 200k tokens 的上下文長(zhǎng)度,且能夠在 1 秒鐘內(nèi)處理近 3 萬字的文本。
    的頭像 發(fā)表于 04-17 15:06 ?469次閱讀

    鴻蒙OS開發(fā)實(shí)例:【ArkTS類庫異步并發(fā)async/await】

    async/await是一種用于處理異步操作的Promise語法糖,使得編寫異步代碼變得更加簡(jiǎn)單和易讀。通過使用async關(guān)鍵聲明一個(gè)函數(shù)為異步函數(shù),并使用await關(guān)鍵
    的頭像 發(fā)表于 04-02 20:57 ?931次閱讀
    鴻蒙OS開發(fā)實(shí)例:【ArkTS類庫<b class='flag-5'>異步</b>并發(fā)async/await】

    阿里通義千問重磅升級(jí),免費(fèi)開放1000萬字長(zhǎng)文檔處理功能

    近日,阿里巴巴旗下的人工智能應(yīng)用通義千問迎來重磅升級(jí),宣布向所有人免費(fèi)開放1000萬字的長(zhǎng)文檔處理功能,這一創(chuàng)新舉措使得通義千問成為全球文檔處理容量第一的AI應(yīng)用。
    的頭像 發(fā)表于 03-26 11:09 ?732次閱讀

    鴻蒙原生應(yīng)用開發(fā)-ArkTS語言基礎(chǔ)類庫異步并發(fā)簡(jiǎn)述async/await

    async/await是一種用于處理異步操作的Promise語法糖,使得編寫異步代碼變得更加簡(jiǎn)單和易讀。通過使用async關(guān)鍵聲明一個(gè)函數(shù)為異步函數(shù),并使用await關(guān)鍵
    發(fā)表于 03-06 14:44

    馬斯克狀告OpenAI,OpenAI回應(yīng)馬斯克訴訟

    馬斯克在長(zhǎng)達(dá)46頁、1.4萬字的訴訟文件中,控訴OpenAI背離了其初衷——即致力于開發(fā)開源人工通用智能(AGI)并服務(wù)全人類。
    的頭像 發(fā)表于 03-04 15:33 ?845次閱讀

    介紹一款基于java的滲透測(cè)試神器-CobaltStrike

    Cobalt Strike是一款基于java的滲透測(cè)試神器,常被業(yè)界人稱為CS神器。
    的頭像 發(fā)表于 01-16 09:16 ?858次閱讀
    介紹一款基于java的滲透測(cè)試<b class='flag-5'>神器</b>-CobaltStrike

    如何用AI聊天機(jī)器人寫出萬字長(zhǎng)文

    如何用AI聊天機(jī)器人寫出萬字長(zhǎng)文
    的頭像 發(fā)表于 12-26 16:25 ?1019次閱讀

    全面!萬字長(zhǎng)文解析全球激光雷達(dá)產(chǎn)業(yè)技術(shù)及市場(chǎng)格局

    在自動(dòng)化駕駛的 5 級(jí)標(biāo)準(zhǔn)中,L3 級(jí)標(biāo)準(zhǔn)下的 ADAS 高級(jí)輔助駕駛市場(chǎng)與 L4、L5 級(jí)標(biāo)準(zhǔn)下的無人駕駛市場(chǎng)都對(duì)激光雷達(dá)技術(shù)產(chǎn)品擁有著較高的需求,隨著中國(guó)自動(dòng)駕駛領(lǐng)域的政策和規(guī)范的不斷成熟,激光雷達(dá)行業(yè)將迎來廣闊的發(fā)展空間。? 根據(jù) Velodyne 預(yù)測(cè),2022 年激光雷達(dá)市場(chǎng)規(guī)模將達(dá)到 119 億美元,其中約 72 億美元來自汽車領(lǐng)域的應(yīng)用,占比約 60%。在自動(dòng)汽車領(lǐng)域中,機(jī)械式和固態(tài)式激光雷達(dá)的技術(shù)發(fā)展方向之爭(zhēng)也將在未來深刻的影響著激光雷達(dá)市場(chǎng)的發(fā)
    的頭像 發(fā)表于 11-20 15:05 ?787次閱讀
    全面!<b class='flag-5'>萬字</b>長(zhǎng)文解析全球激光雷達(dá)產(chǎn)業(yè)技術(shù)及市場(chǎng)格局