public class futuretask<v> extends object
implements future<v>, runnable
可見futuretask 是繼承 future ,産看future源碼得到 public
interface future<v> future ,在future中有個get方法而擷取結果隻有在計算完成時,否則會一直阻塞直到任務轉入完成狀态,然後會傳回結果或者抛出異常。
future中主要定義了5個方法:
1)boolean cancel(boolean mayinterruptifrunning):試圖取消對此任務的執行。如果任務已完成、或已取消,或者由于某些其他原因而無法取消,則此嘗試将失敗。當調用 cancel 時,如果調用成功,而此任務尚未啟動,則此任務将永不運作。如果任務已經啟動,則 mayinterruptifrunning 參數确定是否應該以試圖停止任務的方式來中斷執行此任務的線程。此方法傳回後,對 isdone() 的後續調用将始終傳回
true。如果此方法傳回 true,則對 iscancelled() 的後續調用将始終傳回 true。
2)boolean iscancelled():如果在任務正常完成前将其取消,則傳回 true。
3)boolean isdone():如果任務已完成,則傳回 true。 可能由于正常終止、異常或取消而完成,在所有這些情況中,此方法都将傳回 true。
4)v get()throws interruptedexception,executionexception:如有必要,等待計算完成,然後擷取其結果。
5)v get(long timeout,timeunit unit) throws interruptedexception,executionexception,timeoutexception:如有必要,最多等待為使計算完成所給定的時間之後,擷取其結果(如果結果可用)。
futuretask實作了runnable,所有可通過executor(線程池)來執行,也可轉遞給thread對象來執行。如果在主線程中需要執行比較耗時的操作時,但又不想阻塞主線程時,可以把這些作業交給future對象在背景完成,當主線程将來需要時,就可以通過future對象獲得背景作業的計算結果或者執行狀态。
executor架構利用futuretask來完成異步任務,并可以用來進行任何潛在的耗時的計算。一般futuretask多用于耗時的計算,主線程可以在完成自己的任務後,再去擷取結果。
jdk提供了對future的基本實作,僅在計算完成後才能檢索結果,如果未完成,則阻塞get()方法,一旦計算完成,就不能重新開始或者取消。
可使用futtretask
包裝callable或者runnable對象。因為futuretask實作runnble,是以可将futuretask送出給executor執行。
構造方法摘要
futuretask(callable<v> callable)
建立一個 futuretask,一旦運作就執行給定的 callable。
futuretask(runnable runnable, v result)
建立一個 futuretask,一旦運作就執行給定的 runnable,并安排成功完成時 get 傳回給定的結果 。
參數:
runnable - 可運作的任務。
result - 成功完成時要傳回的結果。
如果不需要特定的結果,則考慮使用下列形式的構造:future<?> f = new futuretask<object>(runnable, null)
下面的例子模拟一個會計算賬的過程,主線程已經獲得其他帳戶的總額了,為了不讓主線程等待 privateaccount類的計算結果的傳回而啟用新的線程去處理, 并使用 futuretask對象來監控,這樣,主線程還可以繼續做其他事情, 最後需要計算總額的時候再嘗試去獲得privateaccount 的資訊。

package test;
import java.util.random;
import java.util.concurrent.callable;
import java.util.concurrent.executionexception;
import java.util.concurrent.futuretask;
/**
*
* @author administrator
*/
@suppresswarnings("all")
public class futuretaskdemo {
public static void main(string[] args) {
// 初始化一個callable對象和futuretask對象
callable paccount = new privateaccount();
futuretask futuretask = new futuretask(paccount);
// 使用futuretask建立一個線程
thread paccountthread = new thread(futuretask);
system.out.println("futuretask線程現在開始啟動,啟動時間為:" + system.nanotime());
paccountthread.start();
system.out.println("主線程開始執行其他任務");
// 從其他賬戶擷取總金額
int totalmoney = new random().nextint(100000);
system.out.println("現在你在其他賬戶中的總金額為" + totalmoney);
system.out.println("等待私有賬戶總金額統計完畢...");
// 測試背景的計算線程是否完成,如果未完成則等待
while (!futuretask.isdone()) {
try {
thread.sleep(500);
system.out.println("私有賬戶計算未完成繼續等待...");
} catch (interruptedexception e) {
e.printstacktrace();
}
}
system.out.println("futuretask線程計算完畢,此時時間為" + system.nanotime());
integer privateaccountmoney = null;
try {
privateaccountmoney = (integer) futuretask.get();
} catch (interruptedexception e) {
e.printstacktrace();
} catch (executionexception e) {
system.out.println("您現在的總金額為:" + totalmoney + privateaccountmoney.intvalue());
}
}
class privateaccount implements callable {
integer totalmoney;
@override
public object call() throws exception {
thread.sleep(5000);
totalmoney = new integer(new random().nextint(10000));
system.out.println("您目前有" + totalmoney + "在您的私有賬戶中");
return totalmoney;
運作結果
futuretask線程現在開始啟動,啟動時間為:3098040622063
主線程開始執行其他任務
現在你在其他賬戶中的總金額為56983
等待私有賬戶總金額統計完畢...
私有賬戶計算未完成繼續等待...
您目前有3345在您的私有賬戶中
futuretask線程計算完畢,此時時間為3103072404138
您現在的總金額為:569833345
public class futuretasksample {
static futuretask<string> future = new futuretask(new callable<string>(){
public string call(){
return getpagecontent();
});
public static void main(string[] args) throws interruptedexception, executionexception{
//start a thread to let this thread to do the time exhausting thing
new thread(future).start();
//main thread can do own required thing first
doownthing();
//at the needed time, main thread can get the result
system.out.println(future.get());
public static string doownthing(){
return "do own thing";
public static string getpagecontent(){
return "testpagecontent and provide that the operation is a time exhausted thing...";
}
下面是callable 和 runnable的介紹:
編寫多線程程式是為了實作多任務的并發執行,進而能夠更好地與使用者互動。一般有三種方法,thread,runnable,callable.
runnable和callable的差別是,
(1)callable規定的方法是call(),runnable規定的方法是run().
(2)callable的任務執行後可傳回值,而runnable的任務是不能傳回值得
(3)call方法可以抛出異常,run方法不可以
(4)運作callable任務可以拿到一個future對象,表示異步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,并檢索計算的結果。通過future對象可以了解任務執行情況,可取消任務的執行,還可擷取執行結果。
1、通過實作runnable接口來建立thread線程:
步驟1:建立實作runnable接口的類:
class somerunnable implements runnable
{
public void run()
{
//do something here
}
}
通過線程池來建立線程:
步驟1:建立線程池:
executorservice pool = executors.newcachedthreadpool();
步驟2:通過runnable對象或callable對象将任務送出給executorservice對象:
future<integer> submit(callable<integer> task);
注釋:future是一個接口,它的定義如下:
public interface future<t>
v get() throws ...;
v get(long timeout, timeunit unit) throws ...;
void cancle(boolean mayinterrupt);
boolean iscancelled();
boolean isdone();
至此,一個線程就建立完成了。
注釋:線程池需調用shutdown();方法來關閉線程。