?一、IO(傳統阻塞式)
? ? 全稱?:Input/Output(輸入/輸出)
? ? 定義?:Java 1.0 引入的基礎 I/O 模型,基于流(Stream)的同步阻塞操作,線程在讀寫數據時會阻塞直到操作完成。
二、NIO(新式非阻塞式)
? ? ?全稱?:
? ? ? ? 官方名稱:New I/O(Java 1.4 引入的新 I/O 庫)
? ? ? ? 技術特性名稱:Non-blocking I/O(非阻塞 I/O)
? ? ?定義?:基于通道(Channel)和緩沖區(Buffer)的同步非阻塞模型,支持多路復用(Selector)和零拷貝等高并發優化。
? ? ?當采用阻塞式的模式時,需要通過accept、read、write這些阻塞式函數進行連接的創建,數據的讀取和寫出,函數返回必須等待這個動作的完成。
? ? ? ? 當調用accept時,必須有新的連接進來時,函數才會返回,并產生新的連接對象。
? ? ? ? 當調用read時,必須得有數據存在時或者連接斷開時,函數才會返回,返回值代表讀取到的數據量或者小于0代表連接斷開。
? ? ? ? 當調用write時,必須等待所發送的數據完全發送完畢或連接斷開時,函數才會返回。
? ? ? ? 基于阻塞的因素,導致軟件無法把多個連接的操作放置在一個線程內,因為如果這樣操作,一旦一個連接發生了阻塞,那么其它連接就無法順利操作下去。所以在這種模式下,通常需要為每個連接配置獨立線程,讀線程是必須的,寫線程依賴業務邏輯,或許可以混合在讀線程中(如果寫總是發生在讀信息之后)。
? ? ? ? 阻塞式模式,意味著10000個連接,至少必須開啟10000個線程為匹配業務,這個對系統的資源開銷太大了。
? ? ? ? 而非阻塞式IO則是為了解決上述問題,以達到高并發的目的。其實最終還是要完成連接的創建、數據的讀寫,設計思想在于是否能夠在做這些操作之前,提前知道是否有數據可讀或是否有空間可寫呢?
? ? ? ? 是的,操作系統都提供了一些內核到用戶態的通知消息,以通知新的連接創建到達、某個連接當下有多少數據可讀,某個連接當下有多少緩存區可寫入數據進行發送。
? ? ? ? 基于上述的這些通知機制,內部管理注冊的多個(10000個)連接,接收對應的通知消息,則可以知道每個連接的狀態,當外部輪訓調用select函數時,返回可讀或可寫的連接,在這個基礎上,外部再進行read或者write。read返回當前可讀到的數據,write寫入緩存可寫入,不再一次性強制寫完,函數返回真真寫入的數據量。
? ? ? ? 簡單來說,在系統的accept、read和write基礎上,添加了一個邏輯層,這一層內通過系統的通知消息,獲知每個連接的狀態信息,從而在通過這一層對應函數調用時,進行連接的狀態判別,避免調用進入系統級別的阻塞式流程。
? ? ? ? Java采用java.nio.channels.Selector類達成NIO的異步邏輯層。