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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【JUC并发编程07】Callable接口

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

文章目錄

    • 7 Callable接口
      • 7.1 Callable接口創建線程
      • 7.2 FutureTask

7 Callable接口

創建線程的多種方式:

  • 繼承Thread類
  • 實現Runnable接口
  • Callable接口
  • 線程池
  • 7.1 Callable接口創建線程

    目前學習了有兩種創建線程的方法,一種是通過創建 Thread 類,另一種是通過使用 Runnable 創建線程,但是,Runnable 缺少的一項功能是,當線程終止時(即 run()完成時),我們無法使線程返回結果。為了支持此功能,Java 中提供了 Callable 接口

    比較Runnable接口和Callable接口

  • Callable中的call()計算結果,如果無法計算結果,會拋出異常

  • Runnable中的run()使用實現接口Runnable的對象創建一個線程時,啟動該線程將導致在獨立執行的線程中調用該對象的run方法
  • 總的來說:run()沒有返回值,不會拋出異常。而call()有返回值,會拋出異常

    因為Thread的構造函數中沒有Callable接口的參數設置,直接替換不可以,只能用下面這種線程創建方法(找一個類,即和Runnable接口有關系,又和Callable接口有關系)

    發現Runnable接口有實現類FutureTask(中間對象)

    FutureTask的構造函數有Callable參數,通過FutureTask創建線程對象

    使用 lambda 方式創建代碼如下:

    public class CallableTest {public static void main(String[] args) throws ExecutionException, InterruptedException {new Thread(()->{System.out.println(Thread.currentThread().getName()+"執行Runnable");}).start();FutureTask<String> task = new FutureTask<>(() -> {System.out.println(Thread.currentThread().getName() + "使用Callable接口");return "Callable接口返回值";});new Thread(task).start();System.out.println("Callable返回值:" + task.get());} }

    輸出為:

    Thread-0執行Runnable Thread-1使用Callable接口 Callable返回值:Callable接口返回值

    詳細代碼可以參考如下代碼

    //比較 callable和runnable 的區別 class MyThread1 implements Runnable{@Overridepublic void run() {//這里沒有返回值} } class MyThread2 implements Callable{@Overridepublic Object call() throws Exception {System.out.println(Thread.currentThread().getName()+"線程運行");return "Callable 的實現線程"; //有返回值} }public class diffentence {public static void main(String[] args) throws ExecutionException, InterruptedException {//創建 實現Runnable 的線程new Thread( new MyThread1(),"t1" ).start();//創建 實現Callable 的線程 不能直接替換 ,沒有這個類型的構造方法// new Thread( new MyThread2(),"t2" ).start();//選擇FutureTask 他是 Runnable 的實現類,而且構造方法含有Callable類型FutureTask<String> task = new FutureTask(new MyThread2());new Thread(task,"hhh").start();System.out.println("返回值"+task.get()); //調用里面的返回值} }

    7.2 FutureTask

    進入FutureTask底層源碼可以看到它的構造器

    // 創建一個FutureTask,一旦運行就執行給定的Callable public FutureTask(Callable<V> callable) {if (callable == null)throw new NullPointerException();this.callable = callable;this.state = NEW; // ensure visibility of callable } // 創建一個FutureTask,一旦運行就執行給定的Ru你那邊了,并安排成功完成時get返回給定的結果 public FutureTask(Runnable runnable, V result) {this.callable = Executors.callable(runnable, result);this.state = NEW; // ensure visibility of callable }

    其他常用的代碼:

    // get()獲取結果 public V get() throws InterruptedException, ExecutionException {int s = state;if (s <= COMPLETING)s = awaitDone(false, 0L);return report(s); } // outcome就是返回值 private V report(int s) throws ExecutionException {Object x = outcome;if (s == NORMAL)return (V)x;if (s >= CANCELLED)throw new CancellationException();throw new ExecutionException((Throwable)x); }

    未來的任務,如果運行過一次,那么下一次,就直接得到結果

    總結

    以上是生活随笔為你收集整理的【JUC并发编程07】Callable接口的全部內容,希望文章能夠幫你解決所遇到的問題。

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