異步機制(Asynchronous) -- (一)開篇兼談Mina

誠惶誠恐。我沒有做過推薦,不知道爲什麼這篇就“被”推薦了。這只是一篇blog,肯定會有不當之處,請包涵,多指正。

 

之前寫了篇blog 專門探討異步/同步IO,但那隻涉及了網絡的IO。這段時間看了很多System方面的論文,且也在設計一個System,再加上最近剛用Mina實現了一個異步消息交互的模塊。因此,將這段時間的心得記錄下來,可能有些雜,希望能夠有人喜歡看。

 

所謂同步,簡單的說,A告訴B去做某件事情,然後就一直等待,直到B做完後返回給A,A才繼續做其它的事情;
所謂異步,相反的,A告訴B做某件事情,然後就去幹其它的事情了,B做完後再通知A。

無論是同步還是異步,其實都是指兩個對象之間的交互。所以,判斷什麼是同步還是異步,首先要先明確指的是哪兩個對象之間的關係。
舉個例子:

這是一段常見的僞代碼,用於Client向Server發送請求。在這裏,可以說socket.write是一個同步IO,因爲調用write操作以後,內核會將要寫的數據放入到網卡的緩衝區中,然後再返回,所以,這裏同步的兩個對象分別是應用程序和內核;也可以說這段代碼是一個同步消息機制,因爲client將request發送給server後,一直等待直到server將response返回,這裏同步的兩個對象分別是client和server。

之前的那篇blog專門論述同步IO和異步IO,它指的是應用程序和操作系統內核間的關係。這裏就不多談了。這裏談談Mina。Mina是一個非常流行的網絡程序的框架,它提供的是異步的API(It provides an abstract • event-driven • asynchronous API)。
比如,如果client想要創建一個到server的連接,用mina可以這樣寫:

看上去好像和一般的寫法沒什麼兩樣。但是,這裏的connector.connect()方法是一個異步的調用,意思是程序告訴mina要去連接address,mina返回說它會做這件事,但它可能還沒有做完。所以,即便“connector.connect(address);”這行代碼結束了,也並不意味着連接成功了(mina這時候可能還正在創建連接的過程中)。完整的寫法應該是:

這裏面最重要的一個類是ConnectListener,它實現了IoFutureListener<ConnectFuture>這個接口。這個類其實只有一個函數 – operationComplete,這是一個回調函數,它告訴mina一旦connect完成以後,就調用這個函數。我們這裏的回調函數,首先判斷一下連接是否成功,如果成功,那麼就向這個鏈接中寫入數據(session.write)。

回調函數在異步機制中扮演着非常重要的角色。 因爲在同步機制中,調用者會等到結果返回然後自己執行接下來的操作,比如,上面這段代碼如果寫成同步的,大概是這個樣子:

但是在異步機制中,就只能將connect後面的代碼做成回調函數,註冊到mina中。這樣,當mina完成工作後它才知道接下去該幹什麼。

值得一提的是,雖然Mina號稱是Asynchronous API,但它也提供了同步的方法。比如,上面這段代碼,如果用Mina的同步機制是這樣寫的:

重點在於“future.awaitUninterruptibly();”這行代碼,它會將程序阻塞住,直到連接創建好,所以,當這行代碼結束後,就可以直接獲取session並執行write操作。

我在網上找到的大部分Mina示例代碼都是基於同步的調用。所以,雖然很多人用mina,可是還是更習慣於同步的機制。至於爲什麼會這樣,以後會再討論。

 

未完待續~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章