Future和FutureTask(多線程)

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:如有必要,最多等待爲使計算完成所給定的時間之後,獲取其結果(如果結果可用)。

 

Java代碼  收藏代碼
  1. public class FutureTask<V>  extends Object  
  2.     implements Future<V>, Runnable  
 FutureTask類是Future 的一個實現,並實現了Runnable,所以可通過Excutor(線程池) 來執行,也可傳遞給Thread對象執行。如果在主線程中需要執行比較耗時的操作時,但又不想阻塞主線程時,可以把這些作業交給Future對象在後臺完成,當主線程將來需要時,就可以通過Future對象獲得後臺作業的計算結果或者執行狀態。 

Executor框架利用FutureTask來完成異步任務,並可以用來進行任何潛在的耗時的計算。一般FutureTask多用於耗時的計算,主線程可以在完成自己的任務後,再去獲取結果。

 

JDK:

此類提供了對 Future 的基本實現。僅在計算完成時才能檢索結果;如果計算尚未完成,則阻塞 get 方法。一旦計算完成,就不能再重新開始或取消計算。


可使用 FutureTask 包裝 Callable 或 Runnable 對象。因爲 FutureTask 實現了 Runnable,所以可將 FutureTask 提交給 Executor 執行。

 

 

Java代碼  收藏代碼
  1. 構造方法摘要  
  2. FutureTask(Callable<V> callable)   
  3.           創建一個 FutureTask,一旦運行就執行給定的 Callable。  
  4.   
  5. FutureTask(Runnable runnable, V result)   
  6.           創建一個 FutureTask,一旦運行就執行給定的 Runnable,並安排成功完成時 get 返回給定的結果 。  
  7. 參數:  
  8. runnable - 可運行的任務。  
  9. result - 成功完成時要返回的結果。  
  10. 如果不需要特定的結果,則考慮使用下列形式的構造:Future<?> f = new FutureTask<Object>(runnable, null)  
 

Example1:

下面的例子模擬一個會計算賬的過程,主線程已經獲得其他帳戶的總額了,爲了不讓主線程等待 PrivateAccount類的計算結果的返回而啓用新的線程去處理, 並使用 FutureTask對象來監控,這樣,主線程還可以繼續做其他事情, 最後需要計算總額的時候再嘗試去獲得privateAccount 的信息。 

 

Java代碼  收藏代碼
  1. package test;  
  2.   
  3. import java.util.Random;  
  4. import java.util.concurrent.Callable;  
  5. import java.util.concurrent.ExecutionException;  
  6. import java.util.concurrent.FutureTask;  
  7.   
  8. /** 
  9.  * 
  10.  * @author Administrator 
  11.  * 
  12.  */  
  13. @SuppressWarnings("all")  
  14. public class FutureTaskDemo {  
  15.     public static void main(String[] args) {  
  16.         // 初始化一個Callable對象和FutureTask對象  
  17.         Callable pAccount = new PrivateAccount();  
  18.         FutureTask futureTask = new FutureTask(pAccount);  
  19.         // 使用futureTask創建一個線程  
  20.         Thread pAccountThread = new Thread(futureTask);  
  21.         System.out.println("futureTask線程現在開始啓動,啓動時間爲:" + System.nanoTime());  
  22.         pAccountThread.start();  
  23.         System.out.println("主線程開始執行其他任務");  
  24.         // 從其他賬戶獲取總金額  
  25.         int totalMoney = new Random().nextInt(100000);  
  26.         System.out.println("現在你在其他賬戶中的總金額爲" + totalMoney);  
  27.         System.out.println("等待私有賬戶總金額統計完畢...");  
  28.         // 測試後臺的計算線程是否完成,如果未完成則等待  
  29.         while (!futureTask.isDone()) {  
  30.             try {  
  31.                 Thread.sleep(500);  
  32.                 System.out.println("私有賬戶計算未完成繼續等待...");  
  33.             } catch (InterruptedException e) {  
  34.                 e.printStackTrace();  
  35.             }  
  36.         }  
  37.         System.out.println("futureTask線程計算完畢,此時時間爲" + System.nanoTime());  
  38.         Integer privateAccountMoney = null;  
  39.         try {  
  40.             privateAccountMoney = (Integer) futureTask.get();  
  41.         } catch (InterruptedException e) {  
  42.             e.printStackTrace();  
  43.         } catch (ExecutionException e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.         System.out.println("您現在的總金額爲:" + totalMoney + privateAccountMoney.intValue());  
  47.     }  
  48. }  
  49.   
  50. @SuppressWarnings("all")  
  51. class PrivateAccount implements Callable {  
  52.     Integer totalMoney;  
  53.   
  54.     @Override  
  55.     public Object call() throws Exception {  
  56.         Thread.sleep(5000);  
  57.         totalMoney = new Integer(new Random().nextInt(10000));  
  58.         System.out.println("您當前有" + totalMoney + "在您的私有賬戶中");  
  59.         return totalMoney;  
  60.     }  
  61.   
  62. }  

 運行結果 



  • futureTask線程現在開始啓動,啓動時間爲:3098040622063 
    主線程開始執行其他任務 
    現在你在其他賬戶中的總金額爲56983 
    等待私有賬戶總金額統計完畢... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    私有賬戶計算未完成繼續等待... 
    您當前有3345在您的私有賬戶中 
    私有賬戶計算未完成繼續等待... 
    futureTask線程計算完畢,此時時間爲3103072404138 
    您現在的總金額爲:569833345 

Example2:
Java代碼  收藏代碼
  1. public class FutureTaskSample {  
  2.       
  3.     static FutureTask<String> future = new FutureTask(new Callable<String>(){  
  4.         public String call(){  
  5.             return getPageContent();  
  6.         }  
  7.     });  
  8.       
  9.     public static void main(String[] args) throws InterruptedException, ExecutionException{  
  10.         //Start a thread to let this thread to do the time exhausting thing  
  11.         new Thread(future).start();  
  12.   
  13.         //Main thread can do own required thing first  
  14.         doOwnThing();  
  15.   
  16.         //At the needed time, main thread can get the result  
  17.         System.out.println(future.get());  
  18.     }  
  19.       
  20.     public static String doOwnThing(){  
  21.         return "Do Own Thing";  
  22.     }  
  23.     public static String getPageContent(){  
  24.         return "testPageContent and provide that the operation is a time exhausted thing...";  
  25.     }  
  26. }  
 來源:http://tomyz0223.iteye.com/blog/1019924
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章