1. 程式人生 > >BIO、NIO、AIO及網路程式設計

BIO、NIO、AIO及網路程式設計

一. 網路程式設計的一些基礎

     1.先說明一下執行緒的掛起、阻塞、睡眠

        執行緒從建立、執行到結束總是處於下面五個狀態之一:新建狀態、就緒狀態、執行狀

        態、阻塞狀態及死亡狀態。下圖是使用時間片輪轉法的作業系統程序的狀態和它們之

        間的轉換。

               掛起和睡眠是主動的,掛起恢復需要主動完成,睡眠恢復則是自動完成的,因為

        睡眠有一個睡眠時間,睡眠時間到則恢復到就緒態。而阻塞是被動的,是在等待某種

        事件或者資源的表現,一旦獲得所需資源或者事件資訊就自動回到就緒態。睡眠和掛

        起是兩種行為,阻塞則是一種狀態。

        掛起:一般是主動的,由系統或程式發出,甚至於輔存中去join()、wait()是掛起。

        阻塞:一般是被動的,在搶佔資源中得不到資源,被動的掛起在記憶體,等待某種資

                   源或訊號量(即有了資源)將他喚醒。sleep()是屬於阻塞。

     2.同步/非同步

        同步和非同步關注的是訊息通訊機制。

      (1)同步:就是指在發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。

                          按照這個定義,其實絕大多數函式都是同步呼叫。

      (2)非同步:概念和同步相對。 當一個非同步過程呼叫發出後,呼叫者不會立刻得到結

                          果。實際處理這個呼叫的部件是在呼叫發出後, 通過狀態、通知來通知

                          呼叫者,或通過回撥函式處理這個呼叫。

      舉例:當到銀行後, .可以去ATM機前排隊等候 – (排隊等候)就是同步等待訊息 .可以去

                 大廳拿號,等到排到我的號時, 櫃檯的人會通知我輪到我去辦理業務. – (等待別

                 人通知)就是非同步等待訊息。

     3.阻塞/非阻塞

        阻塞和非阻塞關注的是程式在等待呼叫結果(訊息,返回值)時的狀態(無所謂同

        步或者非同步,注意這裡的“呼叫結果”就是指“2”中標黑的“呼叫”的結果)

      (1)阻塞:阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起(被掛起就是阻塞,

                          因為是被動的)。函式只有在得到結果之後才會返回。 有人也許會把阻

                          塞呼叫和同步呼叫等同起來,實際上他是不同的。 對於同步呼叫來說,

                          很多時候當前執行緒還是啟用的,只是從邏輯上當前函式沒有返回而已。

      (2)非阻塞:非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函式不

                             會阻塞當前執行緒,而會立刻返回。

        舉例:繼續上面的那個例子,不論是排隊等待,還是使用號碼等待通知,如果在這個

                   等待的過程中,等待者除了等待訊息之外不能做其它的事情,那麼該機制就是

                   阻塞的,表現在程式中,也就是該程式一直阻塞在該函式呼叫處不能繼續往下

                   執行。相反,有的人喜歡在銀行辦理這些業務的時候一邊打打電話發發簡訊一

                   邊等待,這樣的狀態就是非阻塞的。

二. Java BIO、NIO、AIO

      1.概念

       (1)Java BIO : 同步並阻塞,伺服器實現模式為一個連線一個執行緒,即客戶端有連

                                    接請求時伺服器端就需要啟動一個執行緒進行處理,如果這個連線不

                                    做任何事情會造成不必要的執行緒開銷,當然可以通過執行緒池機制改

                                    善。

                                    好理解的解釋:執行緒發起IO請求,不管核心是否準備好IO操作,從

                                                             發起請求起,執行緒一直阻塞,直到操作完成。

       (2)Java NIO : 同步非阻塞,伺服器實現模式為一個請求一個執行緒,即客戶端傳送

                                     的連線請求都會註冊到多路複用器上,多路複用器輪詢到連線有

                                     I/O請求時才啟動一個執行緒進行處理。

                                     好理解的解釋:執行緒發起IO請求,立即返回;核心在做好IO操作的

                                                              準備之後,通過呼叫註冊的回撥函式通知執行緒做IO

                                                              操作,執行緒開始阻塞,直到操作完成。

       (3)Java AIO(NIO.2) : 非同步非阻塞,伺服器實現模式為一個有效請求一個執行緒,客

                                                戶端的I/O請求都是由OS先完成了再通知伺服器應用去啟動

                                                執行緒進行處理。

                                                好理解的解釋:執行緒發起IO請求,立即返回;記憶體做好IO操

                                                                         作的準備之後,做IO操作,直到操作完成或

                                                                         者失敗,通過呼叫註冊的回撥函式通知執行緒

                                                                         做IO操作完成或者失敗

      二. BIO、NIO、AIO的使用場景

          (1)BIO方式適用於連線數目比較小且固定的架構,這種方式對伺服器資源要求比

                   較高,併發侷限於應用中,JDK1.4以前的唯一選擇,但程式直觀簡單易理解。

          (2)NIO方式適用於連線數目多且連線比較短(輕操作)的架構,比如聊天伺服器,

                   併發侷限於應用中,程式設計比較複雜,JDK1.4開始支援。

          (3)AIO方式使用於連線數目多且連線比較長(重操作)的架構,比如相簿伺服器,

                  充分呼叫OS參與併發操作,程式設計比較複雜,JDK7開始支援。