多線程設計模式 - Future模式

Future模式是多線程開發中很是常見的一種設計模式,它的核心思想是異步調用。這相似咱們平常生活中的在線購物流程,帶在購物網看着一件商品時能夠提交表單,當訂單完成後就能夠在家裏等待商品送貨上門。或者說更形象的是咱們發送Ajax請求的時候,頁面是異步的進行後臺處理,用戶無需等待請求的結果,能夠繼續瀏覽或操做其餘內容。設計模式

clipboard.png

如上圖所示,客戶端調用購物請求,服務端程序不等數據處理完成便當即返回客戶端一個僞造的數據,(至關於訂單,而不是真實的商品)這時候由服務端本身偷偷摸摸的發送了一個other call()請求去獲取真實的商品(打包,出庫,送貨)。這就是Future模式的核心所在。
Future模式的主要角色有:
Main:系統啓動,調用FutureClient發出請求
FutureClient:返回Data對象,當即返回FutureData,並開啓線程去獲取RealData
Data:返回數據的接口
FutureData:虛擬數據,返回很快,須要裝載RealData
RealData:真實數據
咱們來看代碼:
Main:多線程

public class Main {
    public static void main(String[] args) {
        FutureClient fc = new FutureClient();
        Data data = fc.getRequset("jianzh5");
        System.out.println("請求完畢...");
        String result = data.getRequest();
        System.out.println("返回的結果:"+result);
    }
}

此類主要調用FutureClient的getRequset方法去返回數據
FutureClient:異步

public class FutureClient {
    public Data getRequset(final String queryStr){
        //初始化代理對象,先返回給客戶端
        final FutureData futureData = new FutureData();
        //啓動一個新的線程去加載真實的數據,傳遞給這個代理對象
        new Thread(new Runnable() {
            @Override public void run() {
                //此線程去加載真實對象,而後傳遞給代理對象
                RealData realData = new RealData(queryStr);
                futureData.setRealData(realData);
            }
        }).start();
        System.out.println("代理對象返回:"+futureData);
        return futureData;
    }
}

該類在接受到用戶請求後很快就能返回虛擬數據 futureData,自己啓動一個線程去獲取真實數據
RealData:ide

public class RealData implements Data{
    private String result;

    public RealData(String queryStr){
        System.out.println("根據參數: "+queryStr+" 進行查詢,這是一個很耗時的操做!");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("裝載完畢,獲取結果");
        result = "查詢結果";
    }

    @Override public String getRequest() {
        return result;
    }
}

RealData裝載數據較慢,這裏使用Sleep(5000)模擬複雜業務邏輯。
FutureData:this

public class FutureData implements Data{
    private RealData realData;
    private boolean isReady = false;

    public synchronized void setRealData(RealData realData){
        //若是已經裝載完畢則直接返回
        if(isReady){
            return;
        }
        //若是未裝載,進行裝載真實數據
        this.realData = realData;
        isReady = true;
        //通知
        notify();
    }

    @Override public synchronized String getRequest() {
        //若是未裝載好一直處於阻塞狀態
        while (!isReady){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //裝載好直接返回數據便可
        return this.realData.getRequest();
    }
}

該類是Future模式的關鍵,它實際是真實數據RealData的代理,封裝了獲取RealData的等待過程實際返回的是真實的數據。
JDK內部類已經實現了Future模式,後續再講!spa

相關文章
相關標籤/搜索