日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Callable和Future接口的实现

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Callable和Future接口的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Callable和Future

Callable接口定義了一個call方法可以作為線程的執行體,但call方法比run方法更強大:

  • call方法可以有返回值
  • call方法可以申明拋出異常
  • Callable接口是JDK5后新增的接口,而且不是Runnable的子接口,所以Callable對象不能直接作為Thread的target。
  • call方法還有一個返回值,call方法不能直接調用,它作為線程的執行體被調用。
  • 那么如何接收call方法的返回值?
    JDK1.5提供了Future接口來代表Callable接口里的call方法的返回值,并為Future接口提供了一個FutureTask實現類,該實現類實現Future接口,并實現了Runnable接口—可以作為Thread的target。
  • 二、Future接口里定義了如下幾個公共方法控制他關聯的Callable任務

  • boolean cancel(Boolean mayInterruptlfRunning):試圖取消該Future里關聯的Callable任務
  • V get():返回Callable任務里的call方法的返回值,調用該方法將導致線程阻塞,必須等到子線程結束才得到返回值
  • V get(long timeout, TimeUnit unit):返回Callable任務里的call方法的返回值,該方法讓程序最多阻塞timeout和unit指定的時間。如果經過指定時間后Callable任務依然沒有返回值,將會拋出TimeoutException。
  • boolean isCancelled:如果在Callable任務正常完成前被取消,則返回true。
  • boolean isDone:如果Callable任務已經完成,則返回true
  • 三、創建、并啟動有返回值的線程的步驟如下

  • 創建Callable接口的實現類,并實現call方法,該call方法的返回值,并作為線程的執行體。
  • 創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call方法的返回值
  • 使用FutureTask對象作為Thread對象的target創建、并啟動新線程
  • 調用FutureTask對象的方法來獲得子線程執行結束后的返回值
  • 四、總結

  • Executor框架使用Runnable作為其任務的基本表達形式。Runnable相當有限,不能返回一個值,也不能拋出受檢查的異常,對于復雜費時的計算更加無法處理

  • 因此產生了Callable和Future這種任務,對任務進行全面管理

  • Callable在主進入點-call處等待返回值,并為可能拋出的異常預先做了準備。

  • Executors包含了一些工具方法將其他類型的任務封裝成一個Callable,比如Runnable和java.security.PrivilegedAction。Runnable和Callable描述的是抽象的計算型任務。

  • 這些任務很有限,有明確的開始和結束,但是對于非常費時的任務比較麻煩,對于已經提交但尚未開始的任務可以取消,但是對于已經開始的任務,只有它們響應中斷,才可以取消。

  • Future描述了任務的生命周期,并提供了相關的方法來獲得任務的結果、取消任務以及檢驗任務已經完成還是被取消。

  • Future意味著任務完成后永遠停留在完成狀態上,就像ExecutorService的生命周期。使用get方法完成任務和異常處理。

  • ExecutorService中的所有submit方法都返回一個Future,可以將一個Runnable或一個Callable提交給executor,然后得到一個Future。也可以顯式地為給定的Runnable或Callable實例化一個FutureTask。

  • 五、例子

    public class CallableInterface {@Testpublic void testCall() throws InterruptedException, ExecutionException {//callable無法直接放到Thread中,而Runnable而已,能否將callable與Runnable扯上關系?就是FutureTask類//FutureTask構造可以傳遞Callable,同時也是Runnable的實現類//FutureTask使用場景:// 1.在主線程中需要執行比較耗時的操作時,但又不想阻塞主線程時,可以把這些作業交給Future對象在后臺完成,當主線程將來需要時,就可以通過Future對象獲得后臺作業的計算結果或者執行狀態。// 2.一般FutureTask多用于耗時的計算,主線程可以在完成自己的任務后,再去獲取結果。// 3.僅在計算完成時才能檢索結果;如果計算尚未完成,則阻塞 get 方法。一旦計算完成,就不能再重新開始或取消計算。// get方法而獲取結果只有在計算完成時獲取,否則會一直阻塞直到任務轉入完成狀態,然后會返回結果或者拋出異常。// 4.只計算一次,get方法放到最后,可以使用isDone方法,判斷是否計算完,再獲取//常規代碼//FutureTask<Integer> futureTask=new FutureTask<>(new RealizeCallable());//lambda//一般FutureTask多用于耗時的計算,如果計算尚未完成,則阻塞 get 方法。// 只計算一次,get方法放到最后,可以使用isDone方法,判斷是否計算完,再獲取。// 復雜的任務,多開幾個線程計算,分支合并。FutureTask<Integer> futureTask1=new FutureTask<>(()-> {System.out.println(Thread.currentThread().getName()+" come in callable");int a=0;for (int i = 0; i < 1000; i++) {a+=i;}return a;});FutureTask<Integer> futureTask2=new FutureTask<>(()-> {System.out.println(Thread.currentThread().getName()+ " come in callable");int a=0;for (int i = 0; i < 20000; i++) {a+=i;}return a;});//創建一個線程Thread thread1=new Thread(futureTask1,"futureTask1");Thread thread2=new Thread(futureTask2,"futureTask2");thread1.start();thread2.start();while (!futureTask1.isDone()){System.out.println("futureTask1 waiting......");}while (!futureTask2.isDone()){System.out.println("futureTask2 waiting......");}System.out.println("futureTask1 result is " +futureTask1.get());System.out.println("futureTask2 result is " +futureTask2.get());System.out.println(Thread.currentThread().getName()+"over");thread1.join();thread2.join();} }

    參考文章

    總結

    以上是生活随笔為你收集整理的Callable和Future接口的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。