原文地址: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?{?? ????? ? ? ? ? ? ? ? ?? ????public?abstract?void?run();?? }??
Callable
Callable與Runnable的功能大致相似,Callable中有一個call()函數(shù),但是call()函數(shù)有返回值,而Runnable的run()函數(shù)不能將結(jié)果返回給客戶程序。Callable的聲明如下 :
[java]?view plaincopy
public?interface?Callable<V>?{?? ????? ? ? ? ? ?? ????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
? ? ? ? ? ? ?? public?interface?Future<V>?{?? ?? ????? ? ? ? ? ? ? ? ? ?? ????boolean?cancel(boolean?mayInterruptIfRunning);?? ?? ????? ? ? ?? ????boolean?isCancelled();?? ?? ????? ? ? ?? ????boolean?isDone();?? ?? ????? ? ? ? ? ?? ????V?get()?throws?InterruptedException,?ExecutionException;?? ?? ????? ? ? ? ? ? ? ?? ????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>?{?? ????? ? ? ?? ????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;????????? }?? ?? public?FutureTask(Runnable?runnable,?V?result)?{?? ????this.callable?=?Executors.callable(runnable,?result);?? ????this.state?=?NEW;????????? }?? 可以看到,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
? ? ?? 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;?? ?? ? ? ? ? ?? public?class?RunnableFutureTask?{?? ?? ????? ? ?? ????static?ExecutorService?mExecutor?=?Executors.newSingleThreadExecutor();?? ?? ????? ? ? ?? ????public?static?void?main(String[]?args)?{?? ????????runnableDemo();?? ????????futureDemo();?? ????}?? ?? ????? ? ?? ????static?void?runnableDemo()?{?? ?? ????????new?Thread(new?Runnable()?{?? ?? ????????????@Override?? ????????????public?void?run()?{?? ????????????????System.out.println("runnable?demo?:?"?+?fibc(20));?? ????????????}?? ????????}).start();?? ????}?? ?? ????? ? ? ? ?? ????static?void?futureDemo()?{?? ????????try?{?? ????????????? ? ?? ????????????Future<?>?result?=?mExecutor.submit(new?Runnable()?{?? ?? ????????????????@Override?? ????????????????public?void?run()?{?? ????????????????????fibc(20);?? ????????????????}?? ????????????});?? ?? ????????????System.out.println("future?result?from?runnable?:?"?+?result.get());?? ?? ????????????? ? ?? ????????????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<Integer>?futureTask?=?new?FutureTask<Integer>(?? ????????????????????new?Callable<Integer>()?{?? ????????????????????????@Override?? ????????????????????????public?Integer?call()?throws?Exception?{?? ????????????????????????????return?fibc(20);?? ????????????????????????}?? ????????????????????});?? ?????????????? ????????????mExecutor.submit(futureTask)?;?? ????????????System.out.println("future?result?from?futureTask?:?"?? ????????????????????+?futureTask.get());?? ?? ????????}?catch?(InterruptedException?e)?{?? ????????????e.printStackTrace();?? ????????}?catch?(ExecutionException?e)?{?? ????????????e.printStackTrace();?? ????????}?? ????}?? ?? ????? ? ? ? ? ?? ????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)容還不錯,歡迎將生活随笔推薦給好友。