【Java】BIO、NIO、AIO网络编程模型概述
前言
我們知道,UNIX環(huán)境下常見的網絡I/O模型有5種:
- 同步阻塞
- 同步非阻塞
- I/O復用
- 信號驅動
- 異步非阻塞
那么基于上述五種模型,Java中,隨著NIO和AIO(NIO 2.0)的引入,一般具有以下三種網絡編程模型:
- BIO
- NIO
- AIO
這次,我們就簡單聊聊這三種網絡編程模型
BIO
BIO是一個經典的網絡編程模型,是通常我們實現一個服務器端程序的過程。
步驟如下:
- 主線程accept請求阻塞。
- 請求到達,創(chuàng)建新的線程來處理這個socket,完成對客戶端的響應。
- 主線程繼續(xù)accept下一個請求。
這個模型的一個明顯的缺點:
當客戶端連接快速增長時,服務器端創(chuàng)建的線程也會驟增,系統性能可能會驟降。
因此,在該模型的基礎上,可以創(chuàng)建線程池,從而避免對每個客戶端線程都創(chuàng)建一個新的服務器端線程,進而提升性能(創(chuàng)建線程是很耗費資源的,盡管線程可以看做輕量級進程)。
可參考Tomcat 的 BIO Connector。
這種方式也有被稱為“偽異步I/O”,因為它是把請求拋到線程池中異步等待處理。
NIO
Java的NIO類庫從JDK1.4(Java4)開始引入,這里NIO主要指非阻塞I/O,主要使用Selector多路復用器來實現的。
Selector在Linux等主流操作系統中是通過epoll實現的。
epoll 詳解
epoll 百度百科
Java NIO Selector 剖析
NIO的實現流程類似于select:
- 創(chuàng)建ServerSocketChannel監(jiān)聽客戶端連接并綁定監(jiān)聽窗口,設置為非阻塞模式。
- 創(chuàng)建Reactor線程,創(chuàng)建多路復用器Selector并啟動線程。
- 將ServerSocketChannel注冊到Reactor線程的Selector上。監(jiān)聽accept事件。
- Selector在線程run方法中無限循環(huán)輪詢準備就緒的key。
- Selector監(jiān)聽到新的客戶端接入,處理新的請求,完成TCP三次握手,建立物理連接。
- 將新的客戶端連接注冊到Selector上,監(jiān)聽讀操作。讀取客戶端發(fā)送的網絡消息。
- 客戶端發(fā)送的數據就緒則讀取客戶端請求,進行處理。
AIO
傳說中的AIO其實是NIO 2.0,Java的AIO類庫從JDK1.7(Java7)引入,它提供了異步文件通道和異步socket通道的實現。
AIO底層在Windows上是通過IOCP實現的,在Linux上則是通過epoll實現的。
IOCP 解讀
IOCP 百度百科
LinuxAsynchronousChannelProvider.java
UnixAsynchronousServerSocketChannelImpl.java
流程:
- 創(chuàng)建AsynchronousServerSocketChannel,綁定監(jiān)聽端口。
- 調用AsynchronousServerSocketChannel的accpet方法,傳入自己實現的CompletionHandler。包括上一步都是非阻塞的。
- 連接傳入,回調CompletionHandler的completed方法,在里面,調用AsynchronousSocketChannel的read方法,傳入負責處理數據的CompletionHandler。
- 數據就緒,觸發(fā)負責處理數據的CompletionHandler的completed方法。繼續(xù)做下一步處理即可。
- 寫入操作類似,也需要傳入CompletionHandler。
AIO比起NIO,有了不少的簡化。
建表做個對比
| 客戶端數目 : 服務器端 I/O 線程數目 | 1 : 1 | m : n | m : 1 | m : 0 |
| 網絡 I/O 模型 | 同步阻塞 I/O | 同步阻塞I/O | 同步非阻塞I/O | 異步非阻塞I/O |
| 吞吐量 | 較低 | 一般 | 較高 | 較高 |
| 編程復雜度 | 比較簡單 | 比較簡單 | 非常復雜 | 比較復雜 |
總結
以上是生活随笔為你收集整理的【Java】BIO、NIO、AIO网络编程模型概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 区块链技术的发展趋势
- 下一篇: 用0和5凑被90整除的max数(洛谷P2