java-23種設計模式-Future模式

1 什麼是Future模式

Future模式是多線程開發中很是常見的一種設計模式。它的核心思想是異步調用。當咱們須要調用一個函數方法時。若是這個函數執行很慢,那麼咱們就要進行等待。但有時候,咱們可能並不急着要結果。所以,咱們可讓被調用者當即返回,讓他在後臺慢慢處理這個請求。對於調用者來講,則能夠先處理一些其餘任務,在真正須要數據的場合再去嘗試獲取須要的數據。設計模式

就像咱們在網上購物,你買了一個包以後會給你生成一個電子的訂單憑證,你只須要持有憑證等待包送過來就好了,這期間你能夠作其餘你想作的事情。bash

對於Future模式來講,它沒法當即返回你須要的數據,可是它會返回一個契約,未來你能夠憑藉這個契約去獲取你須要的信息。多線程

2 Future模式和非Future模式的區別

在傳統的同步方法中調用一些耗時的程序,須要等待一個方法完成後才能進行下一步。而Future模式中客戶端調用完成後並不急於去作處理,而去調用其餘的業務,這樣充分利用了時間,這就是Future模式的核心。app

img

3 Future模式的主要成員

  • Main:系統啓動,調用client發送請求。
  • Client:返回Data對象,當即返回FutureData,並開啓ClientThread線程裝配RealData。
  • Data:返回數據的接口。
  • FutureData:Future數據構造快,可是是一個虛擬的數據,須要裝配RealData。
  • RealData:真實數據。

4 Future模式的簡單實現

Data接口,這個是客戶端但願獲得的數據。異步

public interface Data {
    public String getResult();
}
複製代碼

RealData是最終須要使用的數據模型,使用sleep()模擬構造過程。ide

public class RealData implements Data {
    public final String result;


    public RealData(String result) {
        System.out.println("RealData start " + System.currentTimeMillis());
        //模擬構造時間長
        StringBuffer sb = new StringBuffer();
        for (int i = 0;i<10;i++){
            sb.append(result);
            try{
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("RealData end " + System.currentTimeMillis());
        this.result = sb.toString();
    }

    @Override
    public String getResult() {
        return result;
    }
}
複製代碼

FutureData實現一個快速返回RealData包裝函數

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

    public synchronized void setRealData(RealData realData){
        if (isReady){
            return;
        }
        this.realData = realData;
        isReady = true;
        this.notifyAll();    //realData已經被注入 通知getResult啓動
    }


    @Override
    public synchronized String getResult() {
        while (!isReady){
            try {
                System.out.println("wait start " + System.currentTimeMillis());
                this.wait();     //等待realData被注入
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("wait end " + System.currentTimeMillis());
        return realData.result;
    }
}
複製代碼

客戶端主要實現獲取FutureData,開啓構造RealData線程。ui

main方法調用發起請求。this

public class Client {

    public  Data request(final String queryStr){
        final FutureData future = new FutureData();
        new Thread(){
            @Override
            public void run(){
                System.out.println("run start " + System.currentTimeMillis());
                RealData realData = new RealData(queryStr);
                System.out.println("run end " + System.currentTimeMillis());
                future.setRealData(realData);
            }
        }.start();
        //當即返回futureData
        return future;
    }

    public static void main(String[] args) {
        Client client = new Client();
        //返回的futureData
        Data data = client.request("name");
        System.out.println("請求完成");
        try{
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main end");
        System.out.println(System.currentTimeMillis());
        System.out.println("真實數據"+data.getResult());
    }

}
複製代碼

圖片摘自--簡書spa

相關文章
相關標籤/搜索