軟件模塊之間老是存在着必定的接口,從調用方式上,能夠把他們分爲三類:同步調用、回調和異步調用。同步調用是一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;回調是一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口;異步調用是一種相似消息或事件的機制,不過它的調用方向恰好相反,接口的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的接口)。回調和異步調用的關係很是緊密,一般咱們使用回調來實現異步消息的註冊,經過異步調用來實現消息的通知。同步調用是三者當中最簡單的,而回調又經常是異步調用的基礎
回調你能夠這樣來理解:java
A發送消息給B,B處理好A要求的事情後,將結果返回給A,A再對B返回的結果來作進一步的處理。異步
找到一個利用回調配合異步調用的很不錯的例子,來源於http://kt8668.iteye.com/blog/205739 函數
A、 回調的實現this
/** * 回調接口 * @author KOOK * */ public interface CallBack { /** * 執行回調方法 * @param objects 將處理後的結果做爲參數返回給回調方法 */ public void execute(Object... objects ); }
B、 消息的發送者spa
/** * 簡單本地發送異步消息的類 * @author KOOK * */ public class Local implements CallBack,Runnable{ /** * 遠程接收消息的類,模擬point-to-point */ private Remote remote; /** * 發送出去的消息 */ private String message; public Local(Remote remote, String message) { super(); this.remote = remote; this.message = message; } /** * 發送消息 */ public void sendMessage() { /**當前線程的名稱**/ System.out.println(Thread.currentThread().getName()); /**建立一個新的線程發送消息**/ Thread thread = new Thread(this); thread.start(); /**當前線程繼續執行**/ System.out.println("Message has been sent by Local~!"); } /** * 發送消息後的回調函數 */ public void execute(Object... objects ) { /**打印返回的消息**/ System.out.println(objects[0]); /**打印發送消息的線程名稱**/ System.out.println(Thread.currentThread().getName()); /**中斷髮送消息的線程**/ Thread.interrupted(); } public static void main(String[] args) { Local local = new Local(new Remote(),"Hello"); local.sendMessage(); } public void run() { remote.executeMessage(message, this); } }
C、 遠程消息的接收者線程
/** * 這個類至關於你的同窗 */ public class Remote { /** * 處理消息 * @param msg 接收的消息 * @param callBack 回調函數處理類 */ public void executeMessage(String msg,CallBack callBack) { /**模擬遠程類正在處理其餘事情,可能須要花費許多時間**/ for(int i=0;i<1000000000;i++) { } /**處理完其餘事情,如今來處理消息**/ System.out.println(msg); System.out.println("I hava executed the message by Local"); /**執行回調**/ callBack.execute(new String[]{"Nice to meet you~!"}); //這至關於同窗執行完以後打電話給你 } }
回調的好處之一:摒棄了繼承抽象類方式的回調方式更加簡便靈活 code
來源於 http://hellosure.iteye.com/blog/1130176orm
public abstract class B{ public void execute(){ getConnection(); doCRUD(); releaseConnection(); } public abstract void doCRUD(); public void getConnection(){ System.out.println("得到鏈接..."); } public void releaseConnection(){ System.out.println("釋放鏈接..."); } } public class A extends B{ public void doCRUD(){ System.out.println("執行add操做..."); } public void add(){ doCRUD(); } } public class C extends B{ public void doCRUD(){ System.out.println("執行delete操做..."); } public void delete(){ doCRUD(); } }
若是改成回調實現是這樣的blog
interface CallBack{ public void doCRUD(); } public class HibernateTemplate { public void execute(CallBack action){ getConnection(); action.doCRUD(); releaseConnection(); } public void add(){ execute(new CallBack(){ public void doCRUD(){ System.out.println("執行add操做..."); } }); } public void delete(){ execute(new CallBack(){ public void doCRUD(){ System.out.println("執行delete操做..."); } }); } public void getConnection(){ System.out.println("得到鏈接..."); } public void releaseConnection(){ System.out.println("釋放鏈接..."); } }