轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/6561154.html
一:Future
在使用實現Callable創建線程時,call()方法是有返回值的。那么,我們在編程時用什么來代表這個 線程執行后才能返回的未來結果 呢?那就是 Future類型。
顧名思義,Future——未來值,我們用這個未來值來代替編程中需要用到線程結果的地方,然后在實際運行時,通過 future.get() 方法來獲取線程的真正運行結果。
Future接口有一個泛型參數,其類型與call()方法的返回值類型要一致,也就是說,Future<V> 只是代表 V類型的未來值 而已,不是真的有值存在,需要用到這個具體的值時,就需用V類型的對象future通過get()獲取線程的實際運行結果值。
(注:JDK8中提供了CompletableFuture,用來設置線程的完成時間。Future最令人詬病的就是要等待,要自己去檢查任務是否完成了,在Future中,任務完成的時間是不可控的,CompletableFuture解決了這個問題。)
二:FutureTask
FutureTask是一種可以取消的(在線程執行完成之前取消)異步線程,它實現了Runnable接口和Future接口,也就是說:它既可以運行線程,又可以攜帶返回結果。故:實現runnable創建的線程類、實現callable實現的線程類都可以包裝成FutureTask對象進行啟動。
FutureTask實現了Future接口,故Future中的get()、isDone()、cancel()方法等都得到了具體實現,所以可以通過futuretask對象獲取異步線程的執行結果、查詢線程的完成狀態、取消線程。
FutureTask實現了Runable接口,所以它可以作為Thread類的構造參數被包裝成thread類進行啟動,也可以被提交給線程池的excute(futuretask)進行啟動。
使用過程:創建runnable實現類對象或callable實現類對象——創建FutureTask對象,把runnable實現類對象或callable實現類對象作為參數
——創建Thread對象把futuretask對象作為參數,然后通過thread對象.start()啟動,通過Future<V>類型的list保存異步結果
——或者創建線程池,把futuretask對象作為參數交給excute(futuretask)啟動,通過Future<V>類型的list保存異步結果
——之后可以通過線程的isDone()查詢線程完成狀態,通過 cancel()取消線程,通過future結果的get()獲取真正結果。(若在get()前線程調用了cancel(),則會拋出異常)
