更新時(shí)間:2020-03-27 12:09:59 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2281次
ExecutorService是java中的一個(gè)異步執(zhí)行的框架,通過使用ExecutorService可以方便的創(chuàng)建多線程執(zhí)行環(huán)境。
本文將會(huì)詳細(xì)的講解ExecutorService的具體使用。
創(chuàng)建ExecutorService
通常來說有兩種方法來創(chuàng)建ExecutorService。
第一種方式是使用Executors中的工廠類方法,例如:
ExecutorServiceexecutor=Executors.newFixedThreadPool(10);
除了newFixedThreadPool方法之外,Executors還包含了很多創(chuàng)建ExecutorService的方法。
第二種方法是直接創(chuàng)建一個(gè)ExecutorService,因?yàn)镋xecutorService是一個(gè)interface,我們需要實(shí)例化ExecutorService的一個(gè)實(shí)現(xiàn)。
這里我們使用ThreadPoolExecutor來舉例:
ExecutorServiceexecutorService=
newThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,
newLinkedBlockingQueue<Runnable>());
為ExecutorService分配Tasks
ExecutorService可以執(zhí)行Runnable和Callable的task。其中Runnable是沒有返回值的,而Callable是有返回值的。我們分別看一下兩種情況的使用:
RunnablerunnableTask=()->{
try{
TimeUnit.MILLISECONDS.sleep(300);
}catch(InterruptedExceptione){
e.printStackTrace();
}
};
Callable<String>callableTask=()->{
TimeUnit.MILLISECONDS.sleep(300);
return"Task'sexecution";
};
將task分配給ExecutorService,可以通過調(diào)用xecute(),submit(),invokeAny(),invokeAll()這幾個(gè)方法來實(shí)現(xiàn)。
execute()返回值是void,他用來提交一個(gè)Runnabletask。
executorService.execute(runnableTask);
submit()返回值是Future,它可以提交Runnabletask,也可以提交Callabletask。提交Runnable的有兩個(gè)方法:
<T>Future<T>submit(Runnabletask,Tresult);
Future<?>submit(Runnabletask);
第一個(gè)方法在返回傳入的result。第二個(gè)方法返回null。
再看一下callable的使用:
Future<String>future=
executorService.submit(callableTask);
invokeAny()將一個(gè)task列表傳遞給executorService,并返回其中的一個(gè)成功返回的結(jié)果。
Stringresult=executorService.invokeAny(callableTasks);
invokeAll()將一個(gè)task列表傳遞給executorService,并返回所有成功執(zhí)行的結(jié)果:
List<Future<String>>futures=executorService.invokeAll(callableTasks);
關(guān)閉ExecutorService
如果ExecutorService中的任務(wù)運(yùn)行完畢之后,ExecutorService不會(huì)自動(dòng)關(guān)閉。它會(huì)等待接收新的任務(wù)。如果需要關(guān)閉ExecutorService,我們需要調(diào)用shutdown()或者shutdownNow()方法。
shutdown()會(huì)立即銷毀ExecutorService,它會(huì)讓ExecutorServic停止接收新的任務(wù),并等待現(xiàn)有任務(wù)全部執(zhí)行完畢再銷毀。
executorService.shutdown();
shutdownNow()并不保證所有的任務(wù)都被執(zhí)行完畢,它會(huì)返回一個(gè)未執(zhí)行任務(wù)的列表:
List<Runnable>notExecutedTasks=executorService.shutdownNow();
oracle推薦的最佳關(guān)閉方法是和awaitTermination一起使用:
executorService.shutdown();
try{
if(!executorService.awaitTermination(800,TimeUnit.MILLISECONDS)){
executorService.shutdownNow();
}
}catch(InterruptedExceptione){
executorService.shutdownNow();
}
先停止接收任務(wù),然后再等待一定的時(shí)間讓所有的任務(wù)都執(zhí)行完畢,如果超過了給定的時(shí)間,則立刻結(jié)束任務(wù)。
Future
submit()和invokeAll()都會(huì)返回Future對(duì)象。之前的文章我們已經(jīng)詳細(xì)講過了Future。這里就只列舉一下怎么使用:
Future<String>future=executorService.submit(callableTask);
Stringresult=null;
try{
result=future.get();
}catch(InterruptedException|ExecutionExceptione){
e.printStackTrace();
}
ScheduledExecutorService
ScheduledExecutorService為我們提供了定時(shí)執(zhí)行任務(wù)的機(jī)制。
我們這樣創(chuàng)建ScheduledExecutorService:
ScheduledExecutorServiceexecutorService
=Executors.newSingleThreadScheduledExecutor();
executorService的schedule方法,可以傳入Runnable也可以傳入Callable:
Future<String>future=executorService.schedule(()->{
//...
return"Helloworld";
},1,TimeUnit.SECONDS);
ScheduledFuture<?>scheduledFuture=executorService.schedule(()->{
//...
},1,TimeUnit.SECONDS);
還有兩個(gè)比較相近的方法:
scheduleAtFixedRate(Runnablecommand,longinitialDelay,longperiod,TimeUnitunit)
scheduleWithFixedDelay(Runnablecommand,longinitialDelay,longdelay,TimeUnitunit)
兩者的區(qū)別是前者的period是以任務(wù)開始時(shí)間來計(jì)算的,后者是以任務(wù)結(jié)束時(shí)間來計(jì)算。
ExecutorService和Fork/Join
java7引入了Fork/Join框架。那么兩者的區(qū)別是什么呢?
ExecutorService可以由用戶來自己控制生成的線程,提供了對(duì)線程更加細(xì)粒度的控制。而Fork/Join則是為了讓任務(wù)更加快速的執(zhí)行完畢。
以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Java高級(jí)架構(gòu)師視頻教程,ExecutorService的使用”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)