IO編程
java BIO
網(wǎng)絡編程的基本模型是基于服務器/客戶端喉酌,二者通過三次握手來連接逻卖,并通過socket通信履腋。采用BIO通信模型的服務端帖蔓,通常由一個獨立的Acceptor線程負責監(jiān)聽客戶端的連接企软,在接收到客戶端請求后創(chuàng)建一個單獨的線程與服務器交互庐扫,通過輸出流將結(jié)果返回給客戶端,線程銷毀仗哨。
缺點:缺乏彈性伸縮能力形庭。在高并發(fā)的情況下客戶端進程與服務端進程保持1:1,占用大量系統(tǒng)資源厌漂。
偽異步IO
為了改進這種一連接一線程的模型萨醒,我們可以使用線程池來管理這些線程,實現(xiàn)1個或多個線程處理N個客戶端的模型(但是底層還是使用的同步阻塞I/O)桩卵,通常被稱為“偽異步I/O模型“验靡。
我們知道倍宾,如果使用CachedThreadPool線程池,其實除了能自動幫我們管理線程(復用)胜嗓,看起來也就像是1:1的客戶端:線程數(shù)模型高职,而使用FixedThreadPool我們就有效的控制了線程的最大數(shù)量,保證了系統(tǒng)有限的資源的控制辞州,實現(xiàn)了N:M的偽異步I/O模型怔锌。
但是,正因為限制了線程數(shù)量变过,如果發(fā)生大量并發(fā)請求埃元,超過最大數(shù)量的線程就只能等待,直到線程池中的有空閑的線程可以被復用媚狰。而對Socket的輸入流就行讀取時岛杀,會一直阻塞,直到發(fā)生:
- 有數(shù)據(jù)可讀
- 可用數(shù)據(jù)以及讀取完畢
- 發(fā)生空指針或I/O異常
所以在讀取數(shù)據(jù)較慢時(比如數(shù)據(jù)量大崭孤、網(wǎng)絡傳輸慢等)类嗤,大量并發(fā)的情況下,其他接入的消息辨宠,只能一直等待遗锣,這就是最大的弊端。
NIO和AIO
NIO
一般稱非阻塞IO嗤形,提供了兩種新的套接字通道SocketChannel和ServerSocketChannel精偿。對于低負載使用同步阻塞可以提升開發(fā)效率和可維護性,對于高并發(fā)應使用NIO
- 緩沖區(qū) buffer 實際上是一個數(shù)組赋兵,數(shù)據(jù)的讀入和寫入都通過它
- 通道 channel 區(qū)別于流 全雙工 同時讀寫
- 多路復用器 selector可以不斷輪詢注冊在其上的channel笔咽,如果該channel上發(fā)生讀寫,則可以通過selectorKey獲得通道上的數(shù)據(jù)霹期,進行I/O操作
%NODE_PATH%\bin;