java nio

轉自:http://hi.baidu.com/ggwork/blog/item/d13d74fa134fc9819e5146a1.html

首先了解下所謂的java nio是個什麼東西!


IO是靠字符或字節進行傳輸,比較慢! 而NIO是靠塊, 也就相當於一個Buffer, 一塊一塊 的傳輸, 速度較快 ! 同時加入了多線程 的控制, 一個NIO流可以同時傳輸多個塊等, 也就是所謂的異步傳輸

傳統併發型 服務器設計是利用阻塞型網絡I/O 以多線程的模式(一個SOCKET鏈接,服務端就啓動一個線程接受服務 )來實現的,然而由
於系統常常在進行網絡讀寫時處於阻塞狀態,會大大影響系統的性能 ;自Java1. 4 開始引入
了NIO(新I/O) API,通過使用非阻塞型 I/O ,實現流暢的網絡讀寫操作,爲開發高性能併發
型服務器程序提供了一個很好的解決方案。這就是java nio

首先來看下傳統的阻塞型網絡 I/O的不足 Java 平臺傳統的I/O 系統都是基於Byte(字節)和Stream(數據流)的,相應的I/O 操作都是阻塞型的 , 所以服務器程序也採用阻塞型I/O 進行數據的讀、寫操作。本文以TCP長連接模式來討論併發型服務器的相關設計,爲了實現服務器程序的併發性要求,系統由一個單獨的主線程來監聽用戶發起的 連接請求,一直處於阻塞狀態;當有用戶連接請求到來時,程序都會啓一個新的線程來統一處理用戶數據的讀、寫操作。 這種模式的優點是簡單、實用、易管理;然而缺點也是顯而易見的:由於是爲每一個客戶端分配一個線程來處理輸入、輸出數據,其線程與客戶機的比例近似爲1:1 ,隨着線程數量的不斷增加,服務器啓動了大量的併發線程,會大大加大系統對線程的管理開銷 ,這將成爲吞吐量瓶頸的主要原因 ;其次由於底層的I/O 操作採用的同步模式,I/O 操作的阻塞管理粒度是以服務於請求的線程爲單位的,有可能大量的線程會閒置,處於盲等狀態,造成I/O資源利用率不高,影響整個系統的性能。


對於併發型服務器,系統用在阻塞型I/O 等待和線程間切換的時間遠遠多於 CPU 在內
存中處理數據的時間,因此傳統的阻塞型I/O 已經成爲制約系統性能的瓶頸。Java1.4 版本
後推出的NIO 工具包,提供了非阻塞型I/O 的異步輸入輸出 機制 ,爲提高系統的性能提供
了可實現的基礎機制。

NIO 包及工作原理
針對傳統I/O 工作模式的不足,NIO 工具包提出了基於Buffer(緩衝區)、Channel(通
道)、Selector(選擇器)的新模式;Selector(選擇器)、可選擇的Channel(通道)和
SelectionKey(選擇鍵)配合起來使用,可以實現併發的非阻塞型I/O 能力。

NIO 工具包的成員
Buffer(緩衝器)
Buffer 類是一個抽象類,它有7 個子類分別對應於七種基本的數據類型 :ByteBuffer、
CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer 和ShortBuffer。

每一個Buffer對象相當於一個數據容器 ,可以把它看作內存中 的一個大的數組 ,用來存儲和提取所有基本
類型(boolean 型除外)的數據。Buffer 類的核心是一塊內存區,可以直接對其執行與內存有關
的操作,利用操作系統特性 和能力提高和改善Java 傳統I/O 的性能。


Channel(通道)
Channel 被認爲是NIO 工具包的一大創新點,是(Buffer)緩衝器和I/O 服務之間的通道,
具有雙向性 ,既可以讀入也可以寫出,可以更高效的傳遞數據。

File Stream Object <--> Channel Object <--> Buffer Object

我們這裏主要討論
ServerSocketChannel 和SocketChannel,它們都繼承了SelectableChannel,是可選擇 的通道,
分別可以工作在同步和異步兩種方式下(這裏的可選擇不是 可以選擇兩種工作方式,而是
指可以有選擇註冊 自己感興趣的事件 )。

當通道工作在同步方式 時,它的功能和編程方法與傳統的ServerSocket、Socket 對象相似;

當通道工作在異步工作方式 時,進行輸入輸出處理不必等到輸入輸出完畢才返回,並且可以將其感興趣的(如:接受操作、連接操作、讀出
操作、寫入操作)事件註冊到Selector 對象上,與Selector 對象協同工作可以更有效率的支持和管理併發的網絡套接字連接。


Selector(選擇器)和SelectionKey(選擇鍵)


各類 Buffer 是數據的容器對象;各類Channel 實現在各類Buffer 與各類I/O 服務間傳輸
數據。Selector 是實現併發型非阻塞I/O 的核心,各種可選擇的通道將其感興趣的事件註冊
到Selector 對象上,Selector 在一個循環中不斷輪循監視這各些註冊在其上的Socket 通道。
SelectionKey 類則封裝 了SelectableChannel 對象在Selector 中的註冊信息 。當Selector 監測
到在某個註冊的SelectableChannel 上發生了感興趣的事件時,自動激活產生一個SelectionKey
對象,在這個對象中記錄了哪一個(測試) SelectableChannel 上發生了哪種事件,通過對被激活的
SelectionKey 的分析,外界可以知道每個SelectableChannel 發生的具體事件類型,進行相應的

處理。

 

NIO 工作原理


通過上面的討論,我們可以看出在併發型服務器程序中使用NIO,實際上是通過網絡事
件驅動模型
實現的。我們應用Select 機制 ,不用爲每一個客戶端連接新啓線程處理,而是將
其註冊到特定 的Selector 對象上,這就可以在單線程 中利用Selector 對象管理 大量併發 的網
連接 ,更好的利用了系統資源;採用非阻塞I/O 的通信方式,不要求阻塞等待I/O 操作完
成即可返回,從而減少了管理I/O 連接導致的系統開銷,大幅度提高了系統性能。

當有讀或寫等任何註冊的事件發生時,可以從Selector 中獲得相應的
SelectionKey , 從SelectionKey 中可以找到發生的事件和該事件所發生的具體的
SelectableChannel,以獲得客戶端發送過來的數據。

由於在非阻塞網絡I/O 中採用了事件觸發機制 ,處理程序可以得到系統的主動通知(??? ),從而可以實現底層網絡I/O 無阻塞、流暢地讀寫,而不像在原來的阻塞模式下處理程序需要不斷循環等待。使用NIO,可以編寫出性能更好、更易擴展的併發型服務器程序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章