多執行緒設計模式 - Future模式

  • 2019 年 11 月 27 日
  • 筆記

一起來看看多執行緒設計模式中的Future模式吧~

概述

Future模式是多執行緒開發中非常常見的一種設計模式,它的核心思想是非同步調用。這類似我們日常生活中的在線購物流程,帶在購物網看著一件商品時可以提交表單,當訂單完成後就可以在家裡等待商品送貨上門。或者說更形象的是我們發送Ajax請求的時候,頁面是非同步的進行後台處理,用戶無需等待請求的結果,可以繼續瀏覽或操作其他內容。

如上圖所示,客戶端調用購物請求,服務端程式不等數據處理完成便立即返回客戶端一個偽造的數據,(相當於訂單,而不是真實的商品)這時候由服務端自己偷偷摸摸的發送了一個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:

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:

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模式,詳細內容我們下期再聊!

Tags: