IO一直是軟件開發中的核心部分之一,而隨着互聯網技術的提升,IO的重要性也愈來愈重。縱觀開發界,可以巧妙運用IO,不但對於公司,並且對於開發人員都很是的重要。Java的IO機制也是一直在不斷的完善,以應對日見增多的流量。java
Java IO的方式編程
首先,傳統java.io包提供了諸如File的抽象,輸入,輸出流。交互方式是同步,阻塞;數組
第二,在java 1.4中引入NIO框架(java.nio包),提供了Channel,Selector,Buffer等抽象,構建多路複用的,同步非阻塞IO,同時提供了更接近操做系統底層的高性能數據操做方式;性能優化
第三,在Java 7中,NIO有了進一步的改進,也就是NIO 2。其引入了異步非阻塞IO方式,或者說AIO(Asynchronous IO)。異步IO基於事件和回調機制。網絡
傳統BIO框架
傳統BIO,採用BIO編程通訊模型的服務端,一般由一個獨立的Acceptor線程負責監聽客戶端的鏈接。它接收到客戶端鏈接請求以後爲每一個客戶端建立一個新的線程進行鏈路處理,處理完成後,經過輸出流返回給對應的客戶端,而後銷燬線程。異步
服務端提供IP地址和監聽的端口,客戶端經過TCP的三次握手與之鏈接,鏈接成功後,雙方經過套接字通訊。函數
ServerSocket負責綁定IP地址,啓動監聽端口;Socket負責發起連接操做。鏈接成功,雙方經過輸入和輸出流進行同步阻塞式通訊。性能
「你來了,我才往」的交流方式。優化
ps, Java.net提供的API,如Socket,ServerSocket,HttpURLConnection也歸與同步阻塞IO類庫,由於網絡通訊一樣是IO行爲。
優勢:代碼簡單,直觀,維護方便。
缺點:IO效率極低,影響性能,卻反彈性處理。
當吞吐量增大了,有妙招:線程池。
使用線程池管理線程,避免頻繁建立,銷燬線程的開銷。
可是,其底層使用的依然是同步阻塞IO,一般被稱爲「僞異步IO模型」,真的是治標不治本。
看官留意
IO不單單時對文件的操做,網絡編程中,好比Socket通訊也是典型的IO操做。
輸入流(InputStream),輸出流(OutputStream),用於讀取或寫入字節的(在java中以Stream結尾)。
而Reader/Writer操做字符,增長了字符編解碼等功能(在java中以Reader/Writer結尾)。本質上計算機操做的都是字節,無論是網絡通訊仍是文件讀取,Reader/Writer至關於構建了應用邏輯和原始數據之間的橋樑。
BufferdOutputStream,等帶緩衝區的實現,能夠避免頻繁的磁盤讀寫,進而提升IO處理效率。
區分異步和同步
同步,一種可靠有序的運行機制,在進行同步操做時,後續的任務要等待當前調用返回;
異步,其餘任務不須要等待當前調用是否返回,依靠事件,回調機制來實現任務調用。
阻塞和非阻塞
阻塞,當前線程處於阻塞狀態,沒法從事其餘任務,只有當條件就緒才能繼續;
非阻塞,無論IO操做是否結束,直接返回,相應的操做在後臺繼續處理。
由此總結:同步和異步是結果,阻塞和非阻塞是過程。
NIO
New IO,或者Non-Block IO,非阻塞同步模式。
設計原理:
1. 服務端與客戶端經過Channel通訊;
2. NIO在Channel上讀寫;
3. Channel被註冊到Selector多路複用器上。Selector經過一個線程輪詢這些Channel,找出已經就緒的Channel。
NIO經過線程的輪詢,實現非阻塞IO
NIO的組成部分:
1. Buffer 緩衝區;高效的數據容器
不一樣的是BIO將數據直接讀寫到Stream對象中
NIO的數據操做都是在緩衝區中進行的
緩衝區其實是一個數組,常見類型ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloutBuffer,DoubleBuffer;
2. Channel 在NIO中被用來支持批量式IO操做的一種抽象,與流不一樣,通道是雙向的。
File/Socket,一般被認爲是比較高層次的抽象,而Channel則是更加偏向操做系統底層的一種抽象,這也使得NIO得以充分利用現代操做系統底層機制,進行性能優化。分兩大類:網絡讀寫SelectableChannel(子類包括SocketChannel和ServerSocketChannel);文件操做(FileChannel);
3. Selector 是NIO實現多路複用的基礎。它提供一種高效機制,不斷輪詢註冊在其上的Channel,找出處於就緒狀態,經過SelectionKey取得就緒的Channel集合,進行後續的IO操做。服務端只要提供一個負責Selector輪詢的線程便可,實現單線程對多Channel的高效管理,也是基於操做系統底層機制;
4. Charset 提供Unicode字符串定義,NIO也提供了相應的編解碼等。
Java NIO和IO之間一個最大區別:IO是面向流的,NIO是面向緩衝區的。
AIO (Asynchronous IO)
NIO 2 ,在Java 7提出,NIO的升級版。實現非阻塞異步的通訊模式;
提供異步文件通道和異步套接字通道;
其read,write方法的返回類型都是Future對象;
而Future模型是異步的,其核心思想是:去主函數等待時間;
基於事件和回調機制。
小結
IO,阻塞同步通訊模式,客戶端與服務端三次握手,簡單,吞吐量小。關鍵詞:Socket和ServerSocket;
NIO,非阻塞同步通訊模式,客戶端與服務端經過Channel鏈接,採用多路複用器輪詢註冊的Channel。關鍵詞:SocketChannel 和 ServerSocketChannel;
AIO,非阻塞異步通訊模式,基於事件和回調機制,採用異步通道實現異步通訊。關鍵詞:AsynchronousSocketChannel 和 AsynchronousServerSocketChannel。
寫在後面
主要參考資料