圖解java的BI0,NIO,最簡單直白的理解同步和非同步IO模型
最古老的javaIO通訊模式BIO,即阻塞IO,同步呼叫,效能低:
在伺服器端:有專門的客戶連線 接收器Acceptor,當有新的客戶端連線到達後,Acceptor負責第一步連線,然後給每一個客戶端連線建立一個新的執行緒來處理對應的業務;處理完成後,通過輸出流返回給客戶端,並將執行緒銷燬,這也是最典型的一對一服務模型。
對應模型圖如下:
從圖中可以明顯看出對應Web Browser1,2,3,4 伺服器端分別建立了執行緒New Thread1,2,3,4對應處理來應答對應的請求。
偽非同步模型IO;也被成為M:N客戶服務模型。即通過執行緒池模型的形式用M個執行緒來服務N個客戶端的連線;其中M的大小可以根據伺服器的配置來設定最大值,而可服務客戶端個數N則可以遠遠的大於M.這樣來提高伺服器的服務效率,提高執行緒利用率。同BIO模型類似,只不過,Acceptor接受客戶端請求後,不再獨立啟動執行緒來處理,而是將客戶請求交給執行緒池來處理,從而減少執行緒的建立數量,提高執行緒利用率,增加伺服器的處理能力;
對應的模型如下圖:
從上圖可以看出,M:N的iO模型中的web Browser1,2,3,4最終都由Acceptor交給了Task任務佇列,然後由Thread Pool來執行任務,並將最終的響應結果返回給客戶端。
其中ThreadPool中執行緒的數量M和Task任務佇列的長度的設定,將會影響到伺服器處理客戶端請求的能力,合理的配置執行緒池和Task佇列長度,才能使得伺服器處理能力達到最大;而其具體大小需根據實際需求來決定;
非同步IO:NIO模型;有人叫做New IO,來區別BIO,也有人叫Non-block IO,不過都是表示非阻塞IO,與阻塞Io對應,客戶端的Socket與伺服器端的ServerSocket,分別為:SocketChannel和ServerSocketChannel兩種不同的套接字來實現通訊;不過他們即支援非阻塞通訊模式,也支援阻塞通訊模式,如果使用需要手動設定為非阻塞模式;這也是高效率和高效能的首選模式。
NIO服務端通訊序列圖:
從上圖可以看出伺服器端建立了ServerSocketChannel,建立了多路複用器Selector,然後將伺服器的服務地址和埠繫結到SSC中,並註冊給多路複用器,並啟動多路複用器來處理不同的事件,包括連線事件,讀取事件,寫事件。當然對於每一個客戶端的連線,都必須先建立連線,然後才能非同步讀和非同步寫,但是每一個客戶端的讀寫事件並沒有先後順序,而是通過Selector選擇器輪詢所有的事件,在通過讀寫緩衝區準備好的事件(已經就緒),就會被選中並處理,然後完成對應的事件。如果A客戶端先建立連線,但是需要讀大量資料,則其讀事件就不會處於就緒狀態,也就不會被選擇器選中,而B客戶端後建立連線,但是讀取資料少,很快就處於就緒狀態,那麼伺服器就會處理B的資料,然後將結果寫入寫緩衝區,當寫資料完成並就緒,則會觸發寫事件,返回給客戶端。而此時如果A的讀資料完成處於就緒狀態,則處理器會繼續處理A的讀事件,之後伺服器處理完成,並非同步些人寫緩衝區,處理邏輯同B的寫邏輯;
Nio客戶端通訊時序圖:
從上圖可以看出,客戶端建立SocketChannel並設定為非阻塞模式,並建立多路複用器Selector,客戶端需要先建立連線,然後是非同步讀事件,然後是非同步寫事件,當然客戶端和伺服器端的連線(通道)一旦建立,則輪詢器會不停的判斷,當然也可以設定每過幾秒來輪詢一次,是否處於讀就緒或者寫就緒,如果緩衝已經就緒,則會處理對應的讀寫事件。對於讀寫事件的處理過程基本同伺服器端。