1. 程式人生 > >Java併發程式設計 | 第四篇:Future模式

Java併發程式設計 | 第四篇:Future模式

一、什麼是Future模型

常見的多執行緒設計模式有:單例模式、不變模式、生產者-消費者模式、Future模式;而這裡介紹Future模式,它的核心思想就是非同步呼叫當我們需要呼叫一個函式,但是這個函式執行很慢,如果我們不需要馬上知道結果,我們可以立即返回,讓它在後臺慢慢處理這個請求,對於呼叫者來說,可以先處理一些其他任務,這個就充分利用等待時間在真正需要資料場合再去嘗試獲取需要的資料。
這裡寫圖片描述

二、Future模式的主要角色

主要參與者如表:

參與者 作用
Main 啟動系統,呼叫Client發出請求
Client 返回Data物件,理解返回FutureData,並開啟ClientThread執行緒裝配RealData
Data 返回資料的介面
FutureData Future資料,構造很快,但是是一個虛擬的資料,需要裝配RealData
RealData 真實資料,構造比較慢

核心結構

這裡寫圖片描述

三、Future模式的簡單實現

實現中有一個核心介面就是Data,這是客戶端希望獲取的資料,這個Data介面有兩個重要的實現,分別是RealData,也就是真實資料,這就是我們最終需要獲取的資訊,還有一個FutureData,它用來提取RealData的一個“訂單”因此FutureData可以立即獲得

Data介面

public interface
Data { public String getResult(); }

實現類FutureData

這個是Future模式的關鍵,實際上是真實資料RealData的代理,封裝了獲取RealData的等待過程

public class FutureData implements Data{

    protected RealData realdata=null;//FutureData是RealData的包裝
    protected boolean isReady=false;

    public synchronized void setRealData(RealData realdata){
        if
(isReady){ return; } this.realdata=realdata; isReady=true; notifyAll();//RealData已經被注入,通知getResult() } @Override public synchronized String getResult() { //會等待RealData構造完成 // TODO Auto-generated method stub while(!isReady){ try { wait(); //一直等待,知道RealData被注入 } catch (Exception e) { // TODO: handle exception } } return realdata.result; } }

FutureData實現了一個快速返回的RealData包裝,所以它只是一個包裝,沒有真實資料,在裡面的getResult()方法如果實際資料沒有準備好就等待,直到RealData準備好並注入FutureData才返回資料

實現類RealData

public class RealData implements Data {

    protected final String result;// protected可訪問同包的元素

    public RealData(String para) {
        // RealData的構造可能很慢,需要使用者等待好久,這裡使用sleep模擬
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 10; i++) {
            sb.append(para);

            try {
                Thread.sleep(100);
            } catch (Exception e) {
                // TODO: handle exception
            }
        }

        result = sb.toString();
    }

    @Override
    public String getResult() {
        // TODO Auto-generated method stub

        return result;
    }

}

Client

在客戶端程式,建立獲取FutureData,並開啟構造RealData的執行緒,立即返回FutureData

public class Client {
      public Data request(final String queryStr){
          final FutureData future=new FutureData();//實現獲取FutureData
          new Thread(){        
              public void run(){    //RealData的構造很慢,所以在單獨的執行緒中進行
                  RealData realdata=new RealData(queryStr);
                  future.setRealData(realdata);
              }
          }.start();
          return future;//FutureData會被立即返回
      }

}

主函式

負責呼叫Client發起請求 ,並消費返回的資料


      public static void main(String[] args) {
        Client client=new Client();
        //這裡會立即返回,因為得到FutureData,而不是RealData
        Data data=client.request("name");
        System.out.println("請求完畢");
        try {
            //這裡可以用一個sleep代替對其他業務邏輯的處理
            //在處理這些業務邏輯中,RealData被建立,從而充分利用了等待時間
            Thread.sleep(2000);
        } catch (Exception e) {
            // TODO: handle exception
        }
        System.out.println("資料="+data.getResult());
    }

這裡寫圖片描述
參考:《Java高併發程式設計》