java實現非同步呼叫例項
阿新 • • 發佈:2018-11-16
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
在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; }}
為了簡單化說明(不把它們的關係開得複雜),這裡用Objectb代替了真實資料.而真實的實現中我們應該把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會為你完成所有的工作.