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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java中的Runnable、Callable、Future、FutureTask的区别与示例

發(fā)布時間:2025/3/11 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java中的Runnable、Callable、Future、FutureTask的区别与示例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文地址:http://blog.csdn.net/bboyfeiyu/article/details/24851847

---------------------------------------------------------

Java中存在Runnable、Callable、Future、FutureTask這幾個與線程相關(guān)的類或者接口,在Java中也是比較重要的幾個概念,我們通過下面的簡單示例來了解一下它們的作用于區(qū)別。

Runnable

其中Runnable應(yīng)該是我們最熟悉的接口,它只有一個run()函數(shù),用于將耗時操作寫在其中,該函數(shù)沒有返回值。然后使用某個線程去執(zhí)行該runnable即可實現(xiàn)多線程,Thread類在調(diào)用start()函數(shù)后就是執(zhí)行的是Runnable的run()函數(shù)。Runnable的聲明如下 :?

[java]?view plaincopy
  • public?interface?Runnable?{??
  • ????/**?
  • ?????*?When?an?object?implementing?interface?<code>Runnable</code>?is?used?
  • ?????*?to?create?a?thread,?starting?the?thread?causes?the?object's?
  • ?????*?<code>run</code>?method?to?be?called?in?that?separately?executing?
  • ?????*?thread.?
  • ?????*?<p>?
  • ?????*?
  • ?????*?@see?????java.lang.Thread#run()?
  • ?????*/??
  • ????public?abstract?void?run();??
  • }??
  • Callable

    Callable與Runnable的功能大致相似,Callable中有一個call()函數(shù),但是call()函數(shù)有返回值,而Runnable的run()函數(shù)不能將結(jié)果返回給客戶程序。Callable的聲明如下 :

    [java]?view plaincopy
  • public?interface?Callable<V>?{??
  • ????/**?
  • ?????*?Computes?a?result,?or?throws?an?exception?if?unable?to?do?so.?
  • ?????*?
  • ?????*?@return?computed?result?
  • ?????*?@throws?Exception?if?unable?to?compute?a?result?
  • ?????*/??
  • ????V?call()?throws?Exception;??
  • }??
  • 可以看到,這是一個泛型接口,call()函數(shù)返回的類型就是客戶程序傳遞進來的V類型。

    Future

    Executor就是Runnable和Callable的調(diào)度容器,Future就是對于具體的Runnable或者Callable任務(wù)的執(zhí)行結(jié)果進行

    取消、查詢是否完成、獲取結(jié)果、設(shè)置結(jié)果操作。get方法會阻塞,直到任務(wù)返回結(jié)果(Future簡介)。Future聲明如下 :

    [java]?view plaincopy
  • /**?
  • *?@see?FutureTask?
  • ?*?@see?Executor?
  • ?*?@since?1.5?
  • ?*?@author?Doug?Lea?
  • ?*?@param?<V>?The?result?type?returned?by?this?Future's?<tt>get</tt>?method?
  • ?*/??
  • public?interface?Future<V>?{??
  • ??
  • ????/**?
  • ?????*?Attempts?to?cancel?execution?of?this?task.??This?attempt?will?
  • ?????*?fail?if?the?task?has?already?completed,?has?already?been?cancelled,?
  • ?????*?or?could?not?be?cancelled?for?some?other?reason.?If?successful,?
  • ?????*?and?this?task?has?not?started?when?<tt>cancel</tt>?is?called,?
  • ?????*?this?task?should?never?run.??If?the?task?has?already?started,?
  • ?????*?then?the?<tt>mayInterruptIfRunning</tt>?parameter?determines?
  • ?????*?whether?the?thread?executing?this?task?should?be?interrupted?in?
  • ?????*?an?attempt?to?stop?the?task.?????*?
  • ?????*/??
  • ????boolean?cancel(boolean?mayInterruptIfRunning);??
  • ??
  • ????/**?
  • ?????*?Returns?<tt>true</tt>?if?this?task?was?cancelled?before?it?completed?
  • ?????*?normally.?
  • ?????*/??
  • ????boolean?isCancelled();??
  • ??
  • ????/**?
  • ?????*?Returns?<tt>true</tt>?if?this?task?completed.?
  • ?????*?
  • ?????*/??
  • ????boolean?isDone();??
  • ??
  • ????/**?
  • ?????*?Waits?if?necessary?for?the?computation?to?complete,?and?then?
  • ?????*?retrieves?its?result.?
  • ?????*?
  • ?????*?@return?the?computed?result?
  • ?????*/??
  • ????V?get()?throws?InterruptedException,?ExecutionException;??
  • ??
  • ????/**?
  • ?????*?Waits?if?necessary?for?at?most?the?given?time?for?the?computation?
  • ?????*?to?complete,?and?then?retrieves?its?result,?if?available.?
  • ?????*?
  • ?????*?@param?timeout?the?maximum?time?to?wait?
  • ?????*?@param?unit?the?time?unit?of?the?timeout?argument?
  • ?????*?@return?the?computed?result?
  • ?????*/??
  • ????V?get(long?timeout,?TimeUnit?unit)??
  • ????????throws?InterruptedException,?ExecutionException,?TimeoutException;??
  • }??
  • FutureTask

    FutureTask則是一個RunnableFuture<V>,而RunnableFuture實現(xiàn)了Runnbale又實現(xiàn)了Futrue<V>這兩個接口,

    [java]?view plaincopy
  • public?class?FutureTask<V>?implements?RunnableFuture<V>??
  • RunnableFuture

    [java]?view plaincopy
  • public?interface?RunnableFuture<V>?extends?Runnable,?Future<V>?{??
  • ????/**?
  • ?????*?Sets?this?Future?to?the?result?of?its?computation?
  • ?????*?unless?it?has?been?cancelled.?
  • ?????*/??
  • ????void?run();??
  • }??
  • 另外它還可以包裝Runnable和Callable<V>, 由構(gòu)造函數(shù)注入依賴。

    [java]?view plaincopy
  • 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??
  • }??
  • 可以看到,Runnable注入會被Executors.callable()函數(shù)轉(zhuǎn)換為Callable類型,即FutureTask最終都是執(zhí)行Callable類型的任務(wù)。該適配函數(shù)的實現(xiàn)如下 :

    [java]?view plaincopy
  • public?static?<T>?Callable<T>?callable(Runnable?task,?T?result)?{??
  • ????if?(task?==?null)??
  • ????????throw?new?NullPointerException();??
  • ????return?new?RunnableAdapter<T>(task,?result);??
  • }??
  • RunnableAdapter適配器

    [java]?view plaincopy
  • /**?
  • ?*?A?callable?that?runs?given?task?and?returns?given?result?
  • ?*/??
  • static?final?class?RunnableAdapter<T>?implements?Callable<T>?{??
  • ????final?Runnable?task;??
  • ????final?T?result;??
  • ????RunnableAdapter(Runnable?task,?T?result)?{??
  • ????????this.task?=?task;??
  • ????????this.result?=?result;??
  • ????}??
  • ????public?T?call()?{??
  • ????????task.run();??
  • ????????return?result;??
  • ????}??
  • }??
  • 由于FutureTask實現(xiàn)了Runnable,因此它既可以通過Thread包裝來直接執(zhí)行,也可以提交給ExecuteService來執(zhí)行。

    并且還可以直接通過get()函數(shù)獲取執(zhí)行結(jié)果,該函數(shù)會阻塞,直到結(jié)果返回。因此FutureTask既是Future、

    Runnable,又是包裝了Callable( 如果是Runnable最終也會被轉(zhuǎn)換為Callable ), 它是這兩者的合體。


    簡單示例

    [java]?view plaincopy
  • ?package?com.effective.java.concurrent.task;??
  • ??
  • import?java.util.concurrent.Callable;??
  • import?java.util.concurrent.ExecutionException;??
  • import?java.util.concurrent.ExecutorService;??
  • import?java.util.concurrent.Executors;??
  • import?java.util.concurrent.Future;??
  • import?java.util.concurrent.FutureTask;??
  • ??
  • /**?
  • ?*??
  • ?*?@author?mrsimple?
  • ?*?
  • ?*/??
  • public?class?RunnableFutureTask?{??
  • ??
  • ????/**?
  • ?????*?ExecutorService?
  • ?????*/??
  • ????static?ExecutorService?mExecutor?=?Executors.newSingleThreadExecutor();??
  • ??
  • ????/**?
  • ?????*??
  • ?????*?@param?args?
  • ?????*/??
  • ????public?static?void?main(String[]?args)?{??
  • ????????runnableDemo();??
  • ????????futureDemo();??
  • ????}??
  • ??
  • ????/**?
  • ?????*?runnable,?無返回值?
  • ?????*/??
  • ????static?void?runnableDemo()?{??
  • ??
  • ????????new?Thread(new?Runnable()?{??
  • ??
  • ????????????@Override??
  • ????????????public?void?run()?{??
  • ????????????????System.out.println("runnable?demo?:?"?+?fibc(20));??
  • ????????????}??
  • ????????}).start();??
  • ????}??
  • ??
  • ????/**?
  • ?????*?其中Runnable實現(xiàn)的是void?run()方法,無返回值;Callable實現(xiàn)的是?V?
  • ?????*?call()方法,并且可以返回執(zhí)行結(jié)果。其中Runnable可以提交給Thread來包裝下?
  • ?????*?,直接啟動一個線程來執(zhí)行,而Callable則一般都是提交給ExecuteService來執(zhí)行。?
  • ?????*/??
  • ????static?void?futureDemo()?{??
  • ????????try?{??
  • ????????????/**?
  • ?????????????*?提交runnable則沒有返回值,?future沒有數(shù)據(jù)?
  • ?????????????*/??
  • ????????????Future<?>?result?=?mExecutor.submit(new?Runnable()?{??
  • ??
  • ????????????????@Override??
  • ????????????????public?void?run()?{??
  • ????????????????????fibc(20);??
  • ????????????????}??
  • ????????????});??
  • ??
  • ????????????System.out.println("future?result?from?runnable?:?"?+?result.get());??
  • ??
  • ????????????/**?
  • ?????????????*?提交Callable,?有返回值,?future中能夠獲取返回值?
  • ?????????????*/??
  • ????????????Future<Integer>?result2?=?mExecutor.submit(new?Callable<Integer>()?{??
  • ????????????????@Override??
  • ????????????????public?Integer?call()?throws?Exception?{??
  • ????????????????????return?fibc(20);??
  • ????????????????}??
  • ????????????});??
  • ??
  • ????????????System.out??
  • ????????????????????.println("future?result?from?callable?:?"?+?result2.get());??
  • ??
  • ????????????/**?
  • ?????????????*?FutureTask則是一個RunnableFuture<V>,即實現(xiàn)了Runnbale又實現(xiàn)了Futrue<V>這兩個接口,?
  • ?????????????*?另外它還可以包裝Runnable(實際上會轉(zhuǎn)換為Callable)和Callable?
  • ?????????????*?<V>,所以一般來講是一個符合體了,它可以通過Thread包裝來直接執(zhí)行,也可以提交給ExecuteService來執(zhí)行?
  • ?????????????*?,并且還可以通過v?get()返回執(zhí)行結(jié)果,在線程體沒有執(zhí)行完成的時候,主線程一直阻塞等待,執(zhí)行完則直接返回結(jié)果。?
  • ?????????????*/??
  • ????????????FutureTask<Integer>?futureTask?=?new?FutureTask<Integer>(??
  • ????????????????????new?Callable<Integer>()?{??
  • ????????????????????????@Override??
  • ????????????????????????public?Integer?call()?throws?Exception?{??
  • ????????????????????????????return?fibc(20);??
  • ????????????????????????}??
  • ????????????????????});??
  • ????????????//?提交futureTask??
  • ????????????mExecutor.submit(futureTask)?;??
  • ????????????System.out.println("future?result?from?futureTask?:?"??
  • ????????????????????+?futureTask.get());??
  • ??
  • ????????}?catch?(InterruptedException?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}?catch?(ExecutionException?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ????}??
  • ??
  • ????/**?
  • ?????*?效率底下的斐波那契數(shù)列,?耗時的操作?
  • ?????*??
  • ?????*?@param?num?
  • ?????*?@return?
  • ?????*/??
  • ????static?int?fibc(int?num)?{??
  • ????????if?(num?==?0)?{??
  • ????????????return?0;??
  • ????????}??
  • ????????if?(num?==?1)?{??
  • ????????????return?1;??
  • ????????}??
  • ????????return?fibc(num?-?1)?+?fibc(num?-?2);??
  • ????}??
  • ??
  • }??
  • 輸出結(jié)果




    -------------

    更多的Java,Angular,Android,大數(shù)據(jù),J2EE,Python,數(shù)據(jù)庫,Linux,Java架構(gòu)師,:

    http://www.cnblogs.com/zengmiaogen/p/7083694.html

    總結(jié)

    以上是生活随笔為你收集整理的Java中的Runnable、Callable、Future、FutureTask的区别与示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。