這次為大家介紹的是Java NIO的相關知識,告訴大家什么是NIO,它的工作原理是什么。
NIO是為了彌補傳統I/O工作模式的不足而研發的,NIO的工具包提出了基於Selector(選擇器)、Buffer(緩沖區)、Channel(通道)的新模式;Selector(選擇器)、可選擇的Channel(通道)和SelectionKey(選擇鍵)配合起來使用,可以實現並發的非阻塞型I/O能力。
先來看一下NIO工具包的三個組成部分都是什么?
1. Selector(選擇器)和SelectionKey(選擇鍵)
Buffer是數據的容器對象;Channel實現在Buffer與I/O服務間傳輸數據。Selector是實現並發型非阻塞I/O的核心,可選擇的通道將其感興趣的事件注冊到Selector對象上,Selector不斷輪詢監視着注冊在其上的Socket通道。SelectionKey類封裝了SelectableChannel對象在Selector中的注冊信息。當Selector監測到在某個注冊的SelectableChannel上發生了感興趣的事件時,會自動激活產生一個SelectionKey對象,在該對象中記錄了哪個SelectableChannel上發生了哪種事件,通過對被激活的SelectionKey的分析,外界可以知道每個SelectableChannel發生的具體事件類型,進行相應的處理。
2. Buffer(緩沖器)
Buffer類是一個抽象類,它有7個子類分別對應七種基本的數據類型:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer。每一個Buffer對象相當於一個數據容器,可以把它看作內存中的一個大的數組,用來存儲和提取所有基本類型(boolean型除外)的數據。Buffer類的核心是一塊內存區,可以直接對其執行與內存有關的操作,利用操作系統特性和能力提高和改善Java傳統I/O的性能。
3. Channel(通道)
Channel被認為是NIO工具包的一大創新點,是Buffer(緩沖器)和I/O服務和之間的通道,具有雙向性,既可以寫入也可以讀出,可以更高效地傳遞數據。我們這里主要討論ServerSocketChannel和SocketChannel,它們都繼承了SelectableChannel,是可選擇的通道,分別可以工作在同步和異步兩種方式下(這里的可選擇不是指可以選擇兩種工作方式,而是指可以有選擇地注冊自己感興趣的事件)。當通道工作在同步方式時,它的功能和編程方法與傳統的ServerSocket、Socket對象相似;當通道工作在異步工作方式時,進行輸入輸出處理不必等到輸入輸出完畢才返回,並且可以將其感興趣的事件(如:接受、連接、讀出、寫入等操作)注冊到Selector對象上,與Selector對象協同工作可以更有效率地支持和管理並發的網絡套接字連接。
NIO的工作原理是什么?
在並發型服務器程序中使用NIO,實際上是通過網絡事件驅動模型實現的。我們應用Select機制,不用為每一個客戶端連接新啟線程處理,而是將其注冊到特定的Selector對象上,這就可以在單線程中利用Selector對象管理大量並發的網絡連接,更好的利用了系統資源;采用非阻塞I/O的通信方式,不要求阻塞等待I/O操作完成即可返回,從而減少了管理I/O連接導致的系統開銷,大幅度提高了系統性能。
當有讀或寫等注冊事件發生時,可以從Selector中獲得相應的SelectionKey,從SelectionKey中可以找到發生的事件和該事件所發生的具體的SelectableChannel,以獲得客戶端發送過來的數據。由於在非阻塞網絡I/O中采用了事件觸發機制,處理程序可以得到系統的主動通知,從而可以實現底層網絡I/O無阻塞、流暢地讀寫,而不像在原來的阻塞模式下處理程序需要不斷循環等待。使用NIO,可以編寫出性能更好、更易擴展的並發型服務器程序。
並發型服務器程序的實現代碼:應用NIO工具包,基於非阻塞網絡I/O設計的並發型服務器程序與以往基於阻塞I/O的實現程序有很大不同,在使用非阻塞網絡I/O的情況下,程序讀取數據和寫入數據的時機不是由程序員控制的,而是Selector決定的。
使用非阻塞型I/O進行並發型服務器程序設計分三個部分:1. 向Selector對象注冊感興趣的事件;2.從Selector中獲取所感興趣的事件;3. 根據不同的事件進行相應的處理。
在進行並發型服務器程序設計時,通過合理地使用NIO工具包,就可以達到一個或者幾個Socket線程就可以處理N多個Socket的連接,大大降低我們對服務器程序的預算壓力。同時我們利用它更好地提高系統的性能,使我們的工作得到更加有效地開展。