Future模式

1. Future模式簡介

Future模式就是,當某一程序提交請求,指望獲得一個答覆。可是可能服務器程序對這個請求的處理比較慢,所以不可能立刻收到答覆。可是,在傳統的單線程環境下,調用函數是同步的,它必須等到服務程序返回結果,才能繼續進行其餘處理。而Future模式下,調用方法是異步的,本來等待返回的時間段,在主調函數中,則能夠處理其餘的任務。傳統的串行程序以下圖所示:html

https://images2015.cnblogs.com/blog/805129/201603/805129-20160317205509693-742725053.png

Future模式的處理流程:java

https://images2015.cnblogs.com/blog/805129/201603/805129-20160317205558271-518468971.png

從圖中能夠看出,雖然call()自己是一個須要很長世間處理的程序。可是,服務程序不等數據處理完就馬上返回客戶端一個僞數據,實現Future模式的客戶端在拿到這個返回結果後,並不急於對它進行處理,而是去調用其它的業務邏輯,使call()方法有充分的時間去處理完成,這也是Future模式的精髓所在。 在處理完其餘業務邏輯後,最後再使用處理比較費時的Future數據。這個在處理過程當中,就不存在無謂的等待,充分利用了時間,從而提高了系統的響應和性能。web

2. Future模式的核心結構

下面以一個經典的Future實現爲例,簡單介紹下Future的核心實現。代碼中服務器

  • Data接口:返回數據的接口;
  • FutureData類:實現Data接口,構造很快,返回一個虛擬的僞數據,須要裝配RealData;
  • RealData類:實現Data接口,返回真實數據,構造比較慢;
  • Client:返回Data數據,當即返回FutureData數據,並開啓線程裝配RealData數據。
public interface Data { public String getResult(); } public class FutureData implements Data { protected RealData realData = null; protected boolean isReady = false; //進行同步控制 public synchronized void setResult(RealData realData){ if(isReady){ return; } System.out.println("FutureData.setResult()"); this.realData=realData; isReady = true; notifyAll(); } //實際調用返回RealDate的數據 @Override public synchronized String getResult() { while(!isReady){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("FutureData.getResult()"); return realData.result; } public class RealData implements Data{ protected final String result; public RealData(String s) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) { sb.append(s); try { //模擬構造時間比較長 Thread.sleep(1000); } catch (InterruptedException e) { } } System.out.println("RealData.RealData()"); result = sb.toString(); } public class Client { public Data request(final String queryStr){ //返回僞數據 final FutureData futureData = new FutureData(); //開啓線程構造真實數據 new Thread(){ public void run(){ RealData realData = new RealData(queryStr); futureData.setResult(realData); } }.start(); //返回僞數據,等待真實數據加載 return futureData; } } public interface Data { public String getResult(); } public class FutureData implements Data { protected RealData realData = null; protected boolean isReady = false; //進行同步控制 public synchronized void setResult(RealData realData){ if(isReady){ return; } System.out.println("FutureData.setResult()"); this.realData=realData; isReady = true; notifyAll(); } //實際調用返回RealDate的數據 @Override public synchronized String getResult() { while(!isReady){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("FutureData.getResult()"); return realData.result; } public class RealData implements Data{ protected final String result; public RealData(String s) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) { sb.append(s); try { //模擬構造時間比較長 Thread.sleep(1000); } catch (InterruptedException e) { } } System.out.println("RealData.RealData()"); result = sb.toString(); } public class Client { public Data request(final String queryStr){ //返回僞數據 final FutureData futureData = new FutureData(); //開啓線程構造真實數據 new Thread(){ public void run(){ RealData realData = new RealData(queryStr); futureData.setResult(realData); } }.start(); //返回僞數據,等待真實數據加載 return futureData; } }

啓動系統,調用Client發送請求:併發

public class TestMain { public static void main(String[] args) { Data data = new Client().request("123456"); System.out.println(data); System.out.println(data.getResult()); } } public class TestMain { public static void main(String[] args) { Data data = new Client().request("123456"); System.out.println(data); System.out.println(data.getResult()); } }

能夠看出,FutureData是Future模式實現的關鍵,它實際是真實數據RealData的代理,封裝了獲取RealDate的等待過程.app

3. JDK內置實現

在JDK的內置併發包中,就已經內置了一種Future的實現,提供了更加豐富的線程控制,其基本用意和核心理念與上面實現代碼一致。異步

在JDK中的Future模式中,最重要的是FutureTask類,它實現了Runnable接口,能夠做爲單獨的線程運行。在其run()方法中,經過Sync內部類,調用Callable接口,並維護Callable接口的返回對象。當使用FutureTask.get()時,將返回Callable接口的返回對象。FutureTask還能夠對任務自己進行其餘控制操做。ide

利用Callable接口實現上述例子相同的操做:svg

RealData類的實現:函數

public class Real1Data implements Callable<String>{ private String reaString; public Real1Data(String reaString) { super(); this.reaString = reaString; }    @Override public String call() throws Exception { StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) { sb.append(reaString); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO: handle exception } } return sb.toString(); } } public class Real1Data implements Callable<String>{ private String reaString; public Real1Data(String reaString) { super(); this.reaString = reaString; }    @Override public String call() throws Exception { StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) { sb.append(reaString); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO: handle exception } } return sb.toString(); } }

Client代碼實現:

public class Test1Main { public static void main(String[] args) throws InterruptedException, ExecutionException { FutureTask<String> future = new FutureTask<>(new Real1Data("1111")); ExecutorService exe = Executors.newFixedThreadPool(1); exe.submit(future); System.out.println("FutureTask"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("FutureTask"+future.get()); } } public class Test1Main { public static void main(String[] args) throws InterruptedException, ExecutionException { FutureTask<String> future = new FutureTask<>(new Real1Data("1111")); ExecutorService exe = Executors.newFixedThreadPool(1); exe.submit(future); System.out.println("FutureTask"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("FutureTask"+future.get()); } }

能夠看出RealData的構造速度很快,其核心代碼邏輯放在了call()中實現,再也不須要Data和FutureData,直接經過RealData來構造FutureTask,將其做爲單獨的線程運行。在提交請求後,執行其餘業務邏輯,作好經過FututeTask.get()方法,獲得RealData的執行結果。

Future模式核心在於去除了主調用函數的等待時間,並使得本來須要等待的時間能夠充分利用來處理其餘業務邏輯,充分的利用了系統資源。

參考:
http://www.javashuo.com/article/p-sydbtsov-bn.html
https://www.jianshu.com/p/949d44f3d9e3

相關文章
相關標籤/搜索