關於 BIO & NIO & AIO
必要的基礎
-
IO:輸入輸出(IO)是指計算機同任何外部裝置之間的資料傳遞。
-
同步與非同步
- 同步: 同步就是發起一個呼叫後,被呼叫者未處理完請求之前,呼叫不返回。
- 非同步: 非同步就是發起一個呼叫後,立刻得到被呼叫者的迴應表示已接收到請求,但是被呼叫者並沒有返回結果,此時我們可以處理其他的請求,被呼叫者通常依靠事件,回撥等機制來通知呼叫者其返回結果。
- 同步非同步指的是,當資料已經ready的時候,讀寫操作是同步讀還是非同步讀
-
阻塞與非阻塞
-
阻塞:阻塞就是發起一個請求,呼叫者一直等待請求結果返回,也就是當前執行緒會被掛起,無法從事其他任務,只有當條件就緒才能繼續。
-
非阻塞:非阻塞就是發起一個請求,呼叫者不用一直等著結果返回,可以先去幹其他事情。
-
阻塞與非阻塞指的的是當不能進行讀寫(網絡卡滿時的寫/網絡卡空的時候的讀)的時候,I/O 操作立即返回還是阻塞;
-
-
同/非同步 和 阻塞/非阻塞 關係
- 阻塞與非阻塞指的的是當不能進行讀寫(網絡卡滿時的寫/網絡卡空的時候的讀)的時候,I/O 操作立即返回還是阻塞;同步非同步指的是,當資料已經ready的時候,讀寫操作是同步讀還是非同步讀,階段不同而已。美團技術團隊
那麼同步阻塞(BIO)、同步非阻塞(NIO)和非同步非阻塞(AIO)又代表什麼意思呢?上面的太抽象了
舉個生活中簡單的例子,你媽媽讓你燒水,小時候你比較笨啊,在哪裡傻等著水開(同步阻塞)。等你稍微再長大一點,你知道每次燒水的空隙可以去幹點其他事,然後只需要時不時(輪詢)來看看水開了沒有(同步非阻塞
0、BIO同步阻塞
BIO模型本質上是一對一的通訊,也就是從客戶端發起請求開始,服務端處理請求(如果資源沒有準備好,請求執行緒會一直佔用,直至請求到資源為止,這個過程中其它請求是無法被處理的),當然服務端可以通過多執行緒的方式,實現同時處理多個請求執行緒,但是多執行緒的使用要注意,因為執行緒的建立和管理非常消耗系統資源。所以這種方式對於高併發也是扛不住的。
後來通過執行緒池+訊息佇列的方式,演化出偽非同步IO,服務端維護這個執行緒池和訊息佇列,如果有新的請求,服務端將其打包為一個task物件(該TasK類實現Runnable介面),將此task放入執行緒池中處理,通過訊息佇列的方式確定處理哪一個task,這種偽非同步IO
1、NIO同步非阻塞
NIO在JDK1.4引入,位於JDK的java.nio
包中,NIO主要涉及三個概念:Buffer緩衝區、Selector選擇器、Channel通道;
NIO的特點如下
-
一個執行緒可以處理多個請求
-
NIO提供非阻塞通訊方式,BIO是阻塞的
-
NIO是面向緩衝區的,BIO是面向流的
- java中提供很多緩衝區,如ByteBuffer常用、CharBuffer、...注意StringBuffer不是Buffer緩衝區,它只是一個可以原地動態修改的String型別
- NIO中的通訊時全雙工的,也就是可以同時讀寫操作;而BIO的流中讀寫是單向的。
-
避免同步IO通訊效率過低
-
減小執行緒多的壓力
從圖中我們可以發現,客戶端和服務端可以同時使用NIO模型。
NIO固然好,但是NIO的程式設計難度較大,維護成本較高。所以我們可以使用NIO的框架來降低開發難度,流行基於Java NIO通訊框架有Mina、Netty、Grizzly等
2、AIO非同步非阻塞
AIO也是基於NIO的,不過AIO是非同步非阻塞的。非同步 IO 是基於事件和回撥機制實現的,也就是應用操作之後會直接返回,不會堵塞在那裡,當後臺處理完成,作業系統會通知相應的執行緒進行後續的操作。
參考文章