序言
有時候會遇到一種情況,當流程到了某個一個節點的時候,數據處理需要花費比較長的時間。只是在最後返回成功或者失敗的時候體現,數據處理的結果並不影響後面流程的進展,現在介紹一種設計模式來充分利用時間片段,這個設計模式就是-Future設計模式。
之前的流程圖
上圖顯示的是一個串行程序調用的流程,可以看出當有一個程序執行的操作比較耗時的時候,後面的程序必須等待該模塊的執行完成,才能繼續往下執行。
Future的設計模式流程圖
Future的設計模式可以看出,主線程直接跳過了耗時的子線程,整個流程沒有長時間的等待操作,充分利用了耗時的時間片段,提高了系統的執行效率,與用戶的體驗。
每個角色說一下
1、Main:啓動系統,調用Client發出請求;
2、Client:返回Data對象,理解返回FutureData,並開啓ClientThread線程裝配RealData;
3、Data:返回數據的接口;
4、FutureData:Future數據,構造很快,但是是一個虛擬的數據,需要裝配RealData;
5、RealData:真實數據,構造比較慢。
三、Future模式的代碼實現:
(1)Main函數:
[java] view plain copy
<span style="font-size:18px;">package tgb;
public class Main {
public static void main(String[] args){
Client client = new Client();
//理解返回一個FutureData
Data data = client.request("name");
System.out.println("請求完畢!");
try{
//處理其他業務
//這個過程中,真是數據RealData組裝完成,重複利用等待時間
Thread.sleep(2000);
}catch (Exception e){
}
//真實數據
System.out.println("數據 = "+ data.getResult());
}
}
</span>
(2)Client的實現:
[java] view plain copy
<span style="font-size:18px;">package tgb;
public class Client {
public Data request(final String queryStr){
final FutureData future = new FutureData();
//開啓一個子線程來構造真實數據
new Thread(){
public void run(){
RealData realData = new RealData(queryStr);
future.setRealData(realData); }
}.start();
return future;
}
}
</span>
(3)Data的實現:
[java] view plain copy
<span style="font-size:18px;">package tgb;
public interface Data {
public String getResult();
}
</span>
(4)FutureData:
[java] view plain copy
<span style="font-size:18px;">package tgb;
/**
- 是對RealData的一個包裝
- @author Godfather
-
*/
public class FutureData implements Data {protected RealData realData =null;
protected boolean isReady = false;
public synchronized void setRealData(RealData realData){
if(isReady){
return;
}
this.realData=realData;
isReady=true;
notifyAll();}
@Override
public synchronized String getResult() {
while(!isReady){
try{
wait();
}catch (Exception e){} } return realData.result;
}
}
</span>
(5)RealData實現:
[java] view plain copy
<span style="font-size:18px;">package tgb;
public class RealData implements Data {
protected String result;
public RealData(String para){
//耗時的操作 用Thread.sleep代替一下
StringBuffer sb= new StringBuffer();
for(int i=0;i<10;i++){
sb.append(para);
try{
Thread.sleep(1000);
}catch(Exception e){
}
result= sb.toString();
}
}
@Override
public String getResult() {
return result;
}
}
</span>
注意:
注意真正處理的代碼是 RealData ,所以當 RealData拋出異常的時候,一定要注意處理!具體怎麼處理就要看業務場景了。