Future模式
1. Future模式簡介
Future模式就是,當某一程式提交請求,期望得到一個答覆。但是可能伺服器程式對這個請求的處理比較慢,因此不可能馬上收到答覆。但是,在傳統的單執行緒環境下,呼叫函式是同步的,它必須等到服務程式返回結果,才能繼續進行其他處理。而Future模式下,呼叫方法是非同步的,原本等待返回的時間段,在主調函式中,則可以處理其他的任務。傳統的序列程式如下圖所示:
Future模式的處理流程:
從圖中可以看出,雖然call()本身是一個需要很長世間處理的程式。但是,服務程式不等資料處理完就立刻返回客戶端一個偽資料,實現Future模式的客戶端在拿到這個返回結果後,並不急於對它進行處理,而是去呼叫其它的業務邏輯,使call()方法有充分的時間去處理完成,這也是Future模式的精髓所在。 在處理完其他業務邏輯後,最後再使用處理比較費時的Future資料。這個在處理過程中,就不存在無謂的等待,充分利用了時間,從而提升了系統的響應和效能。
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;
}
}
啟動系統,呼叫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());
}
}
可以看出,FutureData是Future模式實現的關鍵,它實際是真實資料RealData的代理,封裝了獲取RealDate的等待過程.
3. JDK內建實現
在JDK的內建併發包中,就已經內建了一種Future的實現,提供了更加豐富的執行緒控制,其基本用意和核心理念與上面實現程式碼一致。
在JDK中的Future模式中,最重要的是FutureTask類,它實現了Runnable介面,可以作為單獨的執行緒執行。在其run()方法中,通過Sync內部類,呼叫Callable介面,並維護Callable介面的返回物件。當使用FutureTask.get()時,將返回Callable介面的返回物件。FutureTask還可以對任務本身進行其他控制操作。
利用Callable介面實現上述例子相同的操作:
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();
}
}
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());
}
}
可以看出RealData的構造速度很快,其核心程式碼邏輯放在了call()中實現,不再需要Data和FutureData,直接通過RealData來構造FutureTask,將其作為單獨的執行緒執行。在提交請求後,執行其他業務邏輯,做好通過FututeTask.get()方法,得到RealData的執行結果。
Future模式核心在於去除了主呼叫函式的等待時間,並使得原本需要等待的時間可以充分利用來處理其他業務邏輯,充分的利用了系統資源。
參考:
https://www.cnblogs.com/lcngu/p/5289605.html
https://www.jianshu.com/p/949d44f3d9e3
相關文章
- Future 模式之 CompletableFuture模式
- SpringBoot 對Future模式的支援Spring Boot模式
- 【併發程式設計】Future模式新增Callback及Promise 模式程式設計模式Promise
- 深入理解[Future模式]原理與技術模式
- 說一說併發設計模式—Future(非同步)設計模式非同步
- future promise shared_future簡單使用Promise
- 【併發程式設計】Future模式及JDK中的實現程式設計模式JDK
- Guava futureGuava
- Future學習
- Future,FutureTaskCallable關係
- The Future of the English [Supplementary Exercises]
- Java的Future介面Java
- Rust非同步之FutureRust非同步
- Dart中的Future使用Dart
- [Flutter]Dart Future詳解FlutterDart
- Future和CompletableFuture的理解
- Java併發程式設計-Future系列之Future的介紹和基本用法Java程式設計
- Flutter之Future原理解析Flutter
- Java中「Future」介面詳解Java
- 併發-9-Callable和Future
- 在Java中使用Callable和FutureJava
- Flutter的Event Loop、Future及IsolateFlutterOOP
- `std::future`--非同步的優勢非同步
- Runnable,Callable,Future關係淺析
- 聚焦科技女性 - “Her Future, Her Way”
- Flutter非同步程式設計-FutureFlutter非同步程式設計
- C++,std::shared_future的使用C++
- 深入淺出Rust-Future-Part-4Rust
- 深入淺出Rust Future Part-3Rust
- Chapter 1: Plug-in programing from past to the futureAPTAST
- Netty非同步Future原始碼解讀Netty非同步原始碼
- 搞懂Runnable Callable Future FutureTask 及應用
- Java多執行緒-Callable和FutureJava執行緒
- Java多執行緒之Callable,Future,FutureTaskJava執行緒
- Flutter 事件機制 - Future 和 MicroTask 全解析Flutter事件
- Flutter篇之你真的會使用Future嗎?Flutter
- Java非同步之《我call(),Future在哪裡》Java非同步
- Akka系列(五):Java和Scala中的FutureJava