1. 程式人生 > >java-----NIO總結(四)

java-----NIO總結(四)

        我們知道java中的IO經歷了BIO到NIO再到AIO的發展,具體來講的話BIO是同步阻塞式IO,NIO是同步非阻塞式IO,而AIO是非同步非阻塞式IO,前面我們分析了BIO和NIO的用法,至於AIO目前我還沒有研究的想法,先把BIO和NIO研究清楚了再說吧,這篇部落格我對前面的內容進行總結,如果你沒有看過前面的部落格,強烈推薦你看下,下面是索引連結:

java-----NIO總結(三)
        首先是同步/非同步,阻塞/非阻塞的區別:
        同步/非同步是屬於作業系統級別的,指的是作業系統在收到程式請求的IO之後,如果IO資源沒有準備好的話,該如何響應程式的問題,同步的話就是不響應,知道IO資源準備好;而非同步的話則會返回給程式一個標誌,這個標誌用於當IO資源準備好後通過事件機制傳送的內容應該發到什麼地方;
        阻塞/非阻塞是屬於程式級別的,指的是程式在請求作業系統進行IO操作時,如果IO資源沒有準備好的話,程式該怎麼處理的問題,阻塞的話就是程式什麼都不做,一直等到IO資源準備好,非阻塞的話程式則繼續執行,但是會時不時的去檢視下IO到底準備好沒有呢;

        (1):我們常用的Socket用法,它裡面的accept和read都會造成我們程式的阻塞,對於客戶端來說,在發出請求之後,都會一直等待,直到伺服器返回結果或者網路出現異常,對於伺服器端來說,對於客戶端的請求事件只能一個一個的進行處理,這雖然客戶端A和客戶端B的請求是同時傳送的,但是在服務端的執行是順序執行的,可以用下圖來反映這個過程:

                             

        (2):隨後,為了解決服務端正在處理客戶端A的請求的時候不能響應客戶端B請求這個問題,我們為每個客戶端建立了一個執行緒,這樣的話,每個客戶端具體的執行都是在獨立的執行緒中執行的,只要在主執行緒中沒收到一個客戶端連線就建立一個執行緒來處理與這個連線有關的內容就可以了,主執行緒還是繼續監聽有沒有客戶端接入就可以了;這個過程可以通過下圖來反映:

                                

         (3):但是這種方法並沒有解決掉在單個客戶端執行緒中的阻塞現象,在單個執行緒中還是存在一直等待的現象,而且為每個客戶端建立一個對於服務端來說壓力比較大,而且在很多情況下是沒什麼必要的,java為了解決需要建立多個執行緒這個問題,引入了NIO,他在服務端是不需要為每個客戶端都建立一個執行緒的,而只是給Selector建立一個監控執行緒,我們可以使用Selector來監控那些已經準備就緒的通道,將裡面的資料寫入Buffer快取區,或者將Buffer快取區中的資料寫入通道,而且只有Selector可能會陷入阻塞狀態,對於通道和快取區的操作是不會陷入阻塞狀態的;他的具體實現原理圖是:

              

        好了,到這裡,我們對於NIO的知識點總結結束啦,贈人玫瑰,手留餘香!