本文的目的并不是介紹使用的什么技術,而是重點闡述回調接口其實現原理。
一、 異步和同步
講通俗點,異步就是不需要等當前執行的動作完成,就可以繼續執行后面的動作。
通常一個程序執行的順序是:從上到下,依次執行。后面的動作必須等前面動作執行完成以后方可執行。這就是和異步相對的一個概念——同步。
案例:
A、張三打電話給李四,讓李四幫忙寫份材料。
B、李四接到電話的時候,手上有自己的工作要處理,但他答應張三,忙完手上的工作后馬上幫張三寫好材料,并傳真給張三。
C、通完電話后,張三外出辦事。
說明:
張三給李四通完電話后,就出去辦事了,他并不需要等李四把材料寫好才外出。那么張三讓李四寫材料的消息就屬于異步消息。
相反,如果張三必須等李四把材料寫好才能外出辦事的話,那么這個消息就屬于同步消息了。
二、 異步的實現
傳統的程序執行代碼都是從上到下,一條一條執行的。
但生活中有很多情況并不是這樣,以上的案例中,如果李四需要幾個小時以后才能幫張三寫好材料的話,那張三就必須等幾個小時,這樣張三可能會崩潰或者抓狂。
這種一條龍似的處理,顯示不太合理。
可以使用以下辦法來處理這種問題:
張三找王五去給李四打電話,等李四寫好材料后,由王五轉交給張三。這樣張三就可以外出辦其他的事情了。
問題得到了合理的解決,之前張三一條線的工作,由張三和王五兩條線來完成了,兩邊同時進行,彼此不耽誤。
三、 計算機語言的實現
辦法有了,如何用程序來模擬實現呢?
A、以前由一個線程來處理的工作,可以通過新增一個線程來達到異步的目的。這也就是JAVA中的多線程技術。
B、最后李四寫好的材料必須交給張三,以做他用。這就是回調。
回調你可以這樣來理解:
A發送消息給B,B處理好A要求的事情后,將結果返回給A,A再對B返回的結果來做進一步的處理。
四、 Java代碼的實現
A、 回調的實現
1 /** 2 * 回調接口 3 * @author 節奏 4 * 5 */ 6 public interface CallBack { 7 /** 8 * 執行回調方法 9 * @param objects 將處理后的結果作為參數返回給回調方法10 */11 public void execute(Object... objects );12 }
Java是面向對象的語言,因此回調函數就變成了回調接口。
B、 消息的發送者
1 /** 2 * 簡單本地發送異步消息的類 3 * @author 節奏 4 * 5 */ 6 public class Local implements CallBack,Runnable { 7 8 /** 9 * 遠程接收消息的類,模擬point-to-point10 */11 PRivate Remote remote;12 13 /**14 * 發送出去的消息15 */16 private String message;17 18 public Local(Remote remote, String message) {19 super();20 this.remote = remote;21 this.message = message;22 }23 24 /**25 * 發送消息26 */27 public void sendMessage() {28 /**當前線程的名稱**/29 System.out.println(Thread.currentThread().getName());30 /**創建一個新的線程發送消息**/31 Thread thread = new Thread(this);32 thread.start();33 /**當前線程繼續執行**/34 System.out.println("Message has been sent by Local~!");35 }36 37 /**38 * 發送消息后的回調函數39 */40 public void execute(Object... objects ) {41 /**打印返回的消息**/42 System.out.println(objects[0]);43 /**打印發送消息的線程名稱**/44 System.out.println(Thread.currentThread().getName());45 /**中斷發送消息的線程**/46 Thread.interrupted();47 }48 49 public static void main(String[] args) {50 Local local = new Local(new Remote(), "Hello");51 52 local.sendMessage();53 }54 55 public void run() {56 remote.executeMessage(message, this);57 58 }59 }C、 遠程消息的接收者
1 /** 2 * 處理消息的遠程類 3 * @author 節奏 4 * 5 */ 6 public class Remote { 7 8 /** 9 * 處理消息10 * @param msg 接收的消息11 * @param callBack 回調函數處理類12 */13 public void executeMessage(String msg,CallBack callBack) {14 /**模擬遠程類正在處理其他事情,可能需要花費許多時間**/15 for(int i=0;i<1000000000;i++) {16 17 }18 /**處理完其他事情,現在來處理消息**/19 System.out.println(msg);20 System.out.println("I hava executed the message by Local");21 /**執行回調**/22 callBack.execute(new String[]{"Nice to meet you~!"});23 }24 25 }
executeMessage()方法需要接收一個message參數,表示發送出去的消息; 而CallBack參數是他自己,也就是這里的this。表示發送消息后,由Local類自己來處理,調用自身的execute 方法來處理消息結果。
如果這里不是用this,而是用其他的CallBack接口的實現類的話,那就不能稱之為“回調”了,在OO的世界里,那就屬于“委派”。也就是說:“回調”必須是消息的發送者來處理消息結果,否則不能稱之為回調。這個概念必須明確。
新聞熱點
疑難解答