雖然忙碌,但仍小有收穫,開心。編程
BIO: Blocking IO,阻塞式IO緩存
NIO: Non-blocking IO,非阻塞式IO網絡
AIO: Async IO,異步IO多線程
什麼是阻塞式IO/非阻塞式IO,什麼又是同步IO/異步IO呢?框架
① IO實際上分爲兩大步:應用程序請求的IO操做、操做系統的IO操做 - 用戶空間和內核空間(kernel)。用戶空間的應用程序須要IO操做,其實是調用的操做系統的IO操做。異步
② kernel的IO操做是須要時間的 - 姑且叫它準備時間吧。函數
那問題來了:在這個準備時間裏,操做系統和應用程序都是如何工做的?性能
以應用程序讀取數據爲例(這裏不考慮緩存),操做系統其實有兩類回覆:編碼
① 等到須要的數據都準備完畢再回復 -- 中間一直默不做聲,這就是同步IO。操作系統
② 先告訴應用程序數據沒有準備好,而後準備好數據,通知(回調)應用程序或被輪詢 -- 這就是異步IO。
那應用程序如何對待這個響應呢?其實仍是兩類:
① 一直等,直接數據都發過來,而後再進行下一步。-- 阻塞IO。
② 先幹別的,而後按期查詢或等待回調。-- 非阻塞IO。
阻塞/非阻塞IO 說的是應用程序的IO操做;同步/異步IO 說的是操做系統的IO操做。
注意,異步、非阻塞,都有兩個彼此對應的小分類。
前面已經說過,操做系統的IO操做分爲同步IO和異步IO。同步IO沒什麼好說的,咱們就來看看異步IO。
異步IO,實際上是三個系統函數select、poll、epoll中的一個(跟Linux內核版本有關),搞C/C++編程的人應該熟悉這個。
雖然select和poll的性能極高,但能處理的數量有限制,沒記錯的話是不能超過1000個,不然性能下降。
epoll的性能略低(固然仍是很高),但能處理的數量很高。
這幾年的Linux核心用的都是epoll,就是說新版本系統上 JDK NIO調用的是epoll。
感興趣的人能夠查閱相關資料瞭解下。
注意,這裏說的操做系統都是指Linux。
查了一些資料,都是用網絡編程爲例來講明BIO、NIO、AIO的區別,這裏就再也不敲代碼了,直接說說彼此的優缺點好了。
BIO:優勢是編碼簡單,容易上手、調試。缺點則是由於多線程自己的問題,①每一個線程都要分配內存空間(最少128K),②線程的切換須要耗費時間。因此,一是線程數量有限;二是線程多了會嚴重下降響應時間。固然也可使用線程池,但又涉及到隊列任務積壓問題。
NIO:恰好跟BIO相反。優勢是速度快,耗費資源少。缺點是編碼複雜,難以上手、調試。
AIO:這個暫時沒研究,不過想一想應該跟js的回調是一個道理。事件驅動(回調),性能高。
說到NIO,其實不多有直接使用JDK的NIO的,由於有嚴重bug,會致使Linux下select佔用CPU 100%。雖然說後續有改進,但也只是下降了概率,並無完全消除。
因此建議使用Netty、Mina之類的框架,要好的多。
另外,Tomcat,自版本7開始,使用的就是NIO技術,以提高服務性能。