Java併發程式設計 | 第四篇:Future模式
阿新 • • 發佈:2019-01-09
一、什麼是Future模型
常見的多執行緒設計模式有:單例模式、不變模式、生產者-消費者模式、Future模式;而這裡介紹Future模式,它的核心思想就是非同步呼叫。當我們需要呼叫一個函式,但是這個函式執行很慢,如果我們不需要馬上知道結果,我們可以立即返回,讓它在後臺慢慢處理這個請求,對於呼叫者來說,可以先處理一些其他任務,這個就充分利用等待時間,在真正需要資料場合再去嘗試獲取需要的資料。
二、Future模式的主要角色
主要參與者如表:
參與者 | 作用 |
---|---|
Main | 啟動系統,呼叫Client發出請求 |
Client | 返回Data物件,理解返回FutureData,並開啟ClientThread執行緒裝配RealData |
Data | 返回資料的介面 |
FutureData | Future資料,構造很快,但是是一個虛擬的資料,需要裝配RealData |
RealData | 真實資料,構造比較慢 |
核心結構
三、Future模式的簡單實現
實現中有一個核心介面就是Data,這是客戶端希望獲取的資料,這個Data介面有兩個重要的實現,分別是RealData,也就是真實資料,這就是我們最終需要獲取的資訊,還有一個FutureData,它用來提取RealData的一個“訂單”因此FutureData可以立即獲得
Data介面
public interface Data {
public String getResult();
}
實現類FutureData
這個是Future模式的關鍵,實際上是真實資料RealData的代理,封裝了獲取RealData的等待過程
public class FutureData implements Data{
protected RealData realdata=null;//FutureData是RealData的包裝
protected boolean isReady=false;
public synchronized void setRealData(RealData realdata){
if (isReady){
return;
}
this.realdata=realdata;
isReady=true;
notifyAll();//RealData已經被注入,通知getResult()
}
@Override
public synchronized String getResult() { //會等待RealData構造完成
// TODO Auto-generated method stub
while(!isReady){
try {
wait(); //一直等待,知道RealData被注入
} catch (Exception e) {
// TODO: handle exception
}
}
return realdata.result;
}
}
FutureData實現了一個快速返回的RealData包裝,所以它只是一個包裝,沒有真實資料,在裡面的getResult()方法如果實際資料沒有準備好就等待,直到RealData準備好並注入FutureData才返回資料
實現類RealData
public class RealData implements Data {
protected final String result;// protected可訪問同包的元素
public RealData(String para) {
// RealData的構造可能很慢,需要使用者等待好久,這裡使用sleep模擬
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 10; i++) {
sb.append(para);
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
}
result = sb.toString();
}
@Override
public String getResult() {
// TODO Auto-generated method stub
return result;
}
}
Client
在客戶端程式,建立獲取FutureData,並開啟構造RealData的執行緒,立即返回FutureData
public class Client {
public Data request(final String queryStr){
final FutureData future=new FutureData();//實現獲取FutureData
new Thread(){
public void run(){ //RealData的構造很慢,所以在單獨的執行緒中進行
RealData realdata=new RealData(queryStr);
future.setRealData(realdata);
}
}.start();
return future;//FutureData會被立即返回
}
}
主函式
負責呼叫Client發起請求 ,並消費返回的資料
public static void main(String[] args) {
Client client=new Client();
//這裡會立即返回,因為得到FutureData,而不是RealData
Data data=client.request("name");
System.out.println("請求完畢");
try {
//這裡可以用一個sleep代替對其他業務邏輯的處理
//在處理這些業務邏輯中,RealData被建立,從而充分利用了等待時間
Thread.sleep(2000);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("資料="+data.getResult());
}
參考:《Java高併發程式設計》