如果有一個任務需要花一下時間來執行, 可是使用者卻不可以那邊等待任務完成,
這時候就可以使用Future Pattern,
有點像預購iPhone的概念, 我先拿到一個預購單, 等到iPhone來了再拿預購單換實機。
如上圖, 我先給你一個Future Data物件,
但是我會去執行Real Data物件, 等我執行完畢,
則會將結果回傳給你的Future Data物件。
題目: 模擬跟server要一個物件
解法: 使用Future Pattern, server先給你一個Future Data,
等待Real Data好了, 再將結果回傳給Future Data。
先宣告一個Data物件。
public interface Data {
public String getResult();
}
由於只是例子, 只宣告一個回傳結果的方法。
public class FutureData implements Data{
protected RealData mRealData;
public synchronized void setRealData(RealData realData){
mRealData = realData;
notifyAll();
}
public synchronized String getResult() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return mRealData.result;
}
}
接著讓我們的Future Data去實作Data, 宣告兩個方法,
第一個方法是將ReadData物件指派給它, 代表我們的Real Data好了,
因此就可以去把Future Data等待的部分叫醒, 跟它說可以回傳結果了。
第二個方法就是在這邊等待, 讓Real Data來叫醒我, 就可以回傳Real Data的結果。
注意這兩個方法都要使用synchronized關鍵字, 避免上鎖有人開門進來。
那來看Real Data部分
public class RealData implements Data{
protected String result;
public RealData() {}
public void doTask(){
for(int i = 1; i <= 10; i++){
System.out.println(i * 10 + "%");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
result = "completed";
}
@Override
public String getResult() {
return result;
}
}
當Real Data被建立出來的時候, doTask每次迴圈睡1秒用來模擬server執行的進度,
並且映出百分比, 當整段程式碼完成以後, 則顯示完成。
接下來看我們Client物件怎麼呼叫。
public class Client {
private FutureData mFutureData;
public Client(){
mFutureData = new FutureData();
}
public Data request(){
new Thread(){
@Override
public void run() {
System.out.println("start!");
RealData realData = new RealData();
realData.doTask();
mFutureData.setRealData(realData);
}
}.start();
return mFutureData;
}
}
一開始會去建立假物件, 拿到假物件以後就可以使用request,
中間的Thread在request來的時候, 就去建立Real Data,
並且回傳Future Data
剩下主程式
public class Main {
public static void main(String[] args){
Client client = new Client();
Data data = client.request();
System.out.println("result = " + data.getResult());
}
}
動作非常簡單, 只要呼叫Client物件的request, 就可以看到百分比進度開始跑直到結束,
回傳結束的字串。
start!
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
result = completed