Java FutureTask類使用案例解析
FutureTask一個(gè)可取消的異步計(jì)算,F(xiàn)utureTask 實(shí)現(xiàn)了Future的基本方法,提空 start cancel 操作,可以查詢計(jì)算是否已經(jīng)完成,并且可以獲取計(jì)算的結(jié)果。結(jié)果只可以在計(jì)算完成之后獲取,get方法會(huì)阻塞當(dāng)計(jì)算沒(méi)有完成的時(shí)候,一旦計(jì)算已經(jīng)完成,那么計(jì)算就不能再次啟動(dòng)或是取消。
一個(gè)FutureTask 可以用來(lái)包裝一個(gè) Callable 或是一個(gè)runnable對(duì)象。因?yàn)镕urtureTask實(shí)現(xiàn)了Runnable方法,所以一個(gè) FutureTask可以提交(submit)給一個(gè)Excutor執(zhí)行(excution).
FutureTask是java 5引入的一個(gè)類,從名字可以看出來(lái)FutureTask既是一個(gè)Future,又是一個(gè)Task。
我們看下FutureTask的定義:
public class FutureTask<V> implements RunnableFuture<V> { ...}public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run();}
FutureTask實(shí)現(xiàn)了RunnableFuture接口,RunnableFuture接口是Runnable和Future的綜合體。
作為一個(gè)Future,F(xiàn)utureTask可以執(zhí)行異步計(jì)算,可以查看異步程序是否執(zhí)行完畢,并且可以開始和取消程序,并取得程序最終的執(zhí)行結(jié)果。
除此之外,F(xiàn)utureTask還提供了一個(gè)runAndReset()的方法, 該方法可以運(yùn)行task并且重置Future的狀態(tài)。
Callable和Runnable的轉(zhuǎn)換我們知道Callable是有返回值的,而Runnable是沒(méi)有返回值的。Executors提供了很多有用的方法,將Runnable轉(zhuǎn)換為Callable:
public static <T> Callable<T> callable(Runnable task, T result) { if (task == null) throw new NullPointerException(); return new RunnableAdapter<T>(task, result); }
FutureTask內(nèi)部包含一個(gè)Callable,并且可以接受Callable和Runnable作為構(gòu)造函數(shù):
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable } public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable }
它的內(nèi)部就是調(diào)用了Executors.callable(runnable, result);方法進(jìn)行轉(zhuǎn)換的。
以Runnable運(yùn)行
既然是一個(gè)Runnable,那么FutureTask就可以以線程的方式執(zhí)行,我們來(lái)看一個(gè)例子:
@Test public void convertRunnableToCallable() throws ExecutionException, InterruptedException { FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() { @Override public Integer call() throws Exception {log.info('inside callable future task ...');return 0; } }); Thread thread= new Thread(futureTask); thread.start(); log.info(futureTask.get().toString()); }
上面例子是以單個(gè)線程來(lái)執(zhí)行的,同樣我們也可以將FutureTask提交給線程池來(lái)執(zhí)行:
@Test public void workWithExecutorService() throws ExecutionException, InterruptedException { FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() { @Override public Integer call() throws Exception {log.info('inside futureTask');return 1; } }); ExecutorService executor = Executors.newCachedThreadPool(); executor.submit(futureTask); executor.shutdown(); log.info(futureTask.get().toString()); }
本文的例子可參考https://github.com/ddean2009/learn-java-concurrency/tree/master/futureTask
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. Android實(shí)現(xiàn)下載進(jìn)度條效果2. 用js編寫留言板3. Springboot 跨域配置無(wú)效及接口訪問(wèn)報(bào)錯(cuò)的解決方法4. WebSocket使用以及在vue如何使用問(wèn)題5. Java Bean 映射工具 Dozer 2.0 發(fā)布6. PHP設(shè)計(jì)模式之迭代器模式淺析7. php字符串函數(shù) str類常見用法示例8. python argparse模塊通過(guò)后臺(tái)傳遞參數(shù)實(shí)例9. python matplotlib模塊基本圖形繪制方法小結(jié)【直線,曲線,直方圖,餅圖等】10. Spring框架配置java web實(shí)現(xiàn)實(shí)例化
