java實現異步調用實例
在JAVA平臺,實現異步調用的角色有以下三個角色:
調用者 取貨憑證 真實數據
一個調用者在調用耗時操做,不能當即返回數據時,先返回一個取貨憑證.而後在過一斷時間後
憑取貨憑證來獲取真正的數據.
因此連結調用者和真實數據之間的橋樑是取貨憑證.咱們先來看它的實現:
public class FutureTicket{
private Object data = null;
private boolean completed = false;
public synchronized void makeRealData(){
if(this.complited) return;
//獲取數據的耗時操做.這裏用Sleep代替
try{
Thread.sleep(10000);
}catch(Throwable t){}
this.data = "返回的數據內容";
this.completed = true;
notifyAll();
}
public synchronized Object getData(){
while(!this.completed)){
try{
wait();
}catch(Throwable t){}
}
return this.data;
}
public boolean isCompleted(){
return this.completed;
}
}
爲了簡單化說明(不把它們的關係開得複雜),這裏用Objec
tb
代替了真實數據.而真實的實現中咱們應該把makeData放在一個真實數據的類中,而後提供一個方法返回真實數據.這樣對於真實數據的處理和取貨憑證解耦. 對於這個取貨憑證,調用者的如何調用是異步調用的關鍵: publc class Requester{ public FutureTicket request(){ final FutureTicket ft = new FutureTicket(); //在新線程中調用耗時操做 new Thread(){ public void run(){ ft.makeRealData(); } }.start(); return ft; }}在新線程中啓動耗時操做後,不等待線程的完成當即返回提貨單. 而後調用者能夠根據ft.isCompleted()來調用getData()獲取真實數據.固然對ft.isCompleted()測試能夠按規定時間間隔輪巡(極低級的方案),也能夠在條件不知足時wait(),而後等待makeData的notifyAll();這樣你就完成了一個用JAVA模擬的異步操做. 改進:但這樣的調用對於調用者來講仍然要繼續控制線程操做.若是調用者是一個資深的程序員,這固然沒有問題.但假如咱們把對直接數據的處理委託給取貨憑證來作.調用者直接規定對數據的操做,而後由取貨憑證來調用規定的操做,這對於調用者是一個很好的解脫: interface ProcessData{ public void process(Onject data);} public MyProcessData{ public void process(Object data){ //你無論何時起初數據data被獲取了. //你只要規定若是獲取到數據瞭如何處理 System.out.println(data.toString() + "處理完成..........."); //insert into dataBase? }} 取貨憑證在接收調用者請求獲取數據時,要知道對獲取的數據如何處理的方法: public class FutureTicket{ private Object data = null; private boolean completed = false; private ProcessData pd; public FutureTicket(ProcessData pd){ this.pd = pd; } public synchronized void makeRealData(ProcessData pd){ if(this.complited) return; //獲取數據的耗時操做.這裏用Sleep代替 try{ Thread.sleep(10000); }catch(Throwable t){} this.data = "返回的數據內容"; this.completed = true; notifyAll(); } public synchronized void putData(){ while(!this.completed)){ try{ wait(); }catch(Throwable t){} } //return this.data; //不用返回了,直接處理 this.pd.process(this.data); // alert(?); } //這個方法也能夠不要了. public boolean isCompleted(){ return this.completed; }} 調用: final FutureTicket ft = new FutureTicket(new ProcessData()); //在新線程中調用耗時操做 new Thread(){ public void run(){ ft.makeRealData(); } }.start(); ft.putData(); OK,你如今能夠抽菸,喝酒,泡妞.ft會爲你完成全部的工做.
歡迎關注本站公眾號,獲取更多信息