每天一例多執行緒[day15]----Future模式之美麗的謊言
Future模式的適用場景是:想要得到資料時,先返回資料的包裝,非同步獲取真實資料,真正需要時再拿資料,真實資料也許已經非同步得到,也許還在阻塞獲取中...
這有點像BOSS佈置任務,比如由於市場需要,將在本月20號釋出一個版本,今天是10號,分配任務給小弟去做了,詢問小弟能不能搞定,由於小弟著急上位就答應了。而BOSS忙著處理每天的商務問題,在20號之前都沒有空理會給小弟分配的任務。
不知不覺時間到了20號,這時BOSS趕忙詢問小弟做的到底如何了,其實這個時候小弟還差10%沒有搞定,但是不想影響自己以後的信譽就回答已經搞定了,準備晚上部署,BOSS拍了拍小弟肩膀說“好樣的!過一段給你加薪!”,BOSS走開後,小弟立刻拿出自己吃奶的力氣,最終在晚上部署前完成了任務。
思想就是發起請求後會立即返回一個數據給你,但是這個資料只是個包裝,包裝資料會非同步請求真實資料,最終用的時候去拿真實的資料,可能非同步載入完成直接返回,也可能未完成阻塞著。
再比如情人節到了,女朋友問你準備禮物了沒有,明明忘記了,但是依然說準備了,然後偷偷趕緊網購個,對吧!起碼事情算是圓滿了。
-
public interface Data {
-
String getRequest();
-
}
-
public class FutureData implements Data{
-
private RealData realData ;
-
private boolean isReady = false;
-
public Thread currentThread;
-
public synchronized void setRealData(RealData realData) {
-
//如果已經裝載完畢了,就直接返回
-
if(isReady){
-
return;
-
}
-
//如果沒裝載,進行裝載真實物件
-
this.realData = realData;
-
isReady = true;
-
//進行通知
-
notify();
-
}
-
@Override
-
public synchronized String getRequest() {
-
//如果沒裝載好 程式就一直處於阻塞狀態
-
while(!isReady){
-
try {
-
wait();
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
//裝載好直接獲取資料即可
-
return this.realData.getRequest();
-
}
-
}
- <code class="language-java">public class RealData implements Data{
- private String result ;
- public RealData (String queryStr){
- System.out.println("根據" + queryStr + "進行查詢,這是一個很耗時的操作..");
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("操作完畢,獲取結果");
- result = "查詢結果";
- }
- @Override
- public String getRequest() {
- return result;
- }
- }
- </code>
-
public class FutureClient {
-
public FutureData request(final String queryStr){
-
//1 我想要一個代理物件(Data介面的實現類)先返回給傳送請求的客戶端,告訴他請求已經接收到,可以做其他的事情
-
final FutureData futureData = new FutureData();
-
//2 啟動一個新的執行緒,去載入真實的資料,傳遞給這個代理物件
-
Thread t = new Thread(new Runnable() {
-
@Override
-
public void run() {
-
//3 這個新的執行緒可以去慢慢的載入真實物件,然後傳遞給代理物件
-
RealData realData = new RealData(queryStr);
-
futureData.setRealData(realData);
-
}
-
});
-
t.start();
-
futureData.currentThread = t;
-
return futureData;
-
}
-
}
-
public class Main {
-
public static void main(String[] args) throws InterruptedException {
-
FutureClient fc = new FutureClient();
-
FutureData data = fc.request("請求引數");
-
System.out.println("請求傳送成功!");
-
System.out.println("做其他的事情..."+"請求資料執行緒狀態:"+data.currentThread.getState());
-
//經測試程式碼阻塞在這一行,等待獲取真實資料,而 以上程式碼則實時執行
-
String result = data.getRequest();
-
System.out.println(result+"請求資料的執行緒狀態:"+data.currentThread.getState());
-
}