架構師養成記--9.future模式講解


  什么是future模式呢?解釋這個概念之前我們先來了解一個場景吧,財務系統的結賬功能,這個功能可能是每個月用一次,在這一個月中相關的數據量已經積累得非常大,這一個功能需要調用好幾個存儲過程來完成。假如要調用5個存儲過程,每個存儲過程要執行5分鍾左右,那么這5個加起來就要25分鍾。現在用戶要求優化,把結賬功能的時間控制在10分鍾之內,那么該怎么做呢?解決方案就是將5個存儲過程按照業務划分成幾個組,這幾個組並行執行。其實也就類似ajax的異步請求,主線程可以做其他的事情,耗時的業務讓子線程去完成,子線程完成后將數據放在指定的地方,主線程需要的時候再去指定的地方去拿數據。下面代碼中FutureData 巧妙地使用了wait和notify方法來保證數據的獲取與加載的協調性。

public class FutureClient {

    public Data request(final String queryStr){
        //1 我想要一個代理對象(Data接口的實現類)先返回給發送請求的客戶端,告訴他請求已經接收到,可以做其他的事情
        final FutureData futureData = new FutureData();
        //2 啟動一個新的線程,去加載真實的數據,傳遞給這個代理對象
        new Thread(new Runnable() {
            @Override
            public void run() {
                //3 這個新的線程可以去慢慢的加載真實對象,然后傳遞給代理對象
                RealData realData = new RealData(queryStr);
                futureData.setRealData(realData);
            }
        }).start();
        
        return futureData;
    }
    
}
public interface Data {

    String getRequest();

}
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();
    }


}
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;
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM