- Future模式,也是非常經典的設計模式,這種模式主要就利用空間換時間的概念,也就是說異步執行(需要開啟一個新的線程)
- 在互聯網高并發的應用服務中,我們隨處可見這種理念和代碼,主要就是使用了這種模式
- ?Future模式非常適合在處理耗時很長的業務邏輯時進行使用,可以有效的減小系統的響應時間,提高系統的吞吐量
package com.example.core.juc;import java.util.concurrent.*;public class UseFuture implements Callable<String> {private String param;public UseFuture(String param){this.param = param;}@Overridepublic String call() throws Exception{//模擬執行業務的耗時Thread.sleep(3000);String result = this.param =",處理完成";return result;}public static void main(String[] args) throws InterruptedException, ExecutionException {String queryStr1 = "query1";String queryStr2 = "query2";FutureTask<String> future1 = new FutureTask<String>(new UseFuture(queryStr1));FutureTask<String> future2 = new FutureTask<String>(new UseFuture(queryStr2));ExecutorService executorService = Executors.newFixedThreadPool(2);executorService.submit(future1);//異步的操作executorService.submit(future2);//異步的操作System.out.println("處理其他的任務");Thread.sleep(2000);String ret1 = future1.get();String ret2 = future2.get();System.out.println("數據處理完成"+ret1);System.out.println("數據處理完成"+ret2);
/*
output:
處理其他的任務
數據處理完成,處理完成
數據處理完成,處理完成*/}
}
future設計模式
- 最為關鍵的就是FutureData包裝類,當客戶端發出請求,FutureData會接收并返回請求,但是此時這個call return并不包含真是的數據,FutureData會發送other call去獲取真實的數據類,再將真實的數據類返回,用于真正的實際使用。
- Future模式有點類似于商品訂單。 比如在網購時,當看重某一件商品事,就可以提交訂單,當訂單處理完成后,在家里等待商品送貨上門即可
- ?或者說更形象的我們發送Ajax請求的時候,頁面是異步的進行后臺處理,用戶無須一直等待請求的結果,可以繼續瀏覽或操作其他內容
例子
- 網購時,當看重某一件商品事,就可以提交訂單,當訂單處理完成后,在家里等待商品送貨上門即可
- 當客戶端發起請求,返回包裝類對象,另外起一個線程去查詢數據,再將真實的數據返回
- Main.java
package com.example.core.future;public class Main {public static void main(String[] args) {FutureClient fc = new FutureClient();Data data = fc.request("請求參數");//異步執行System.out.println("做其他的相關業務操作");String rst = data.getRequest();//這才是真正的獲取實際數據的方法System.out.println("---"+rst);}
}
/*
做其他的相關業務操作
根據查詢參數:請求參數進行查詢數據庫操作這可能需要5秒左右的時間
---100條數據*/
- Data抽象層?
package com.example.core.future;public interface Data {String getRequest();
}
- FutureClient.java
package com.example.core.future;public class FutureClient {public Data request(final String queryStr){FutureData futureData = new FutureData();//異步的起一個線程去進行相應的處理操作new Thread(new Runnable() {@Overridepublic void run() {//需要把請求的參數 設置到真實數據的處理對象中去RealData realData = new RealData(queryStr);//真實請求處理完成之后,我們需要進行設置,將結果給包裝對象futureData.setRealData(realData);}}).start();;return futureData;}
}
- FutureData.java
package com.example.core.future;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();}@Overridepublic synchronized String getRequest() {while(!isReady){try{wait();}catch (InterruptedException e){e.printStackTrace();}}return this.realData.getRequest();}
}
- RealData.java
package com.example.core.future;public class RealData implements Data{private String result;public RealData(String queryStr){System.out.println("根據查詢參數:"+queryStr+"進行查詢數據庫操作這可能需要5秒左右的時間");try{//時間的查詢耗時Thread.sleep(5000);}catch (InterruptedException e){e.printStackTrace();}result = "100條數據";}@Overridepublic String getRequest() {return result;}
}
?
?