摘要:選擇器核心類,能夠檢測多個注冊的通道上是否有事件發生,因此一個線程可以管理多個通道。標記,記錄當前的位置,可以通過恢復到的位置。而返回值記錄了包括,,集合和集合等。學習參考系列教程入門
一、NIO的核心部分
通道(channel):用于讀操作和寫操作,主要負責數據的“運輸”。相當于傳統IO中的stream,不過stream是單向的。
緩沖區(buffer):一個容器,用于存儲數據。
選擇器(selector):核心類,能夠檢測多個注冊的通道上是否有事件發生,因此一個線程可以管理多個通道。
使用NIO主要就是為了提高IO的速度
傳統IO是基于字節流和字符進行操作的,而NIO是基于通道(channel)和緩沖區(buffer)進行操作的,這樣一來數據的偏移操作非常方便。
傳統IO是阻塞的,如果發出IO請求后數據沒有就緒,會處于阻塞狀態,而NIO通過通道操作數據,因此一個通道無數據可讀,可以切換到另一個通道。
NIO有選擇器,因此單線程可以操作多個通道。
三、簡單的NIO讀和寫例子
從文件中讀取
與傳統IO不同的是,使用NIO從文件中讀取主要分為三步:
(1)從FileInputStream中獲取channel;
FileInputStream fin = new FileInputStream( "readandshow.txt" ); FileChannel fc = fin.getChannel();
(2)創建buffer;
ByteBuffer buffer = ByteBuffer.allocate( 1024 );
(3)將數據從channel讀到buffer中。
fc.read( buffer );
寫入文件
類似的,利用NIO寫入文件也分為三步:
(1)從FileInputStream中獲取channel;
FileOutputStream fout = new FileOutputStream( "writesomebytes.txt" ); FileChannel fc = fout.getChannel();
(2)創建一個緩沖區并在其中放入一些數據;
ByteBuffer buffer = ByteBuffer.allocate( 1024 ); for (int i=0; i(3)將數據從buffer寫到通道中。
fc.write( buffer );四、buffer內部細節flip()函數源碼
public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }這里可以注意到limit,position和mark三個變量
五、選擇器
(1) capacity:表明可以儲存在緩沖區中的最大數據容量。
(2) position:下一個可插入的位置(寫buffer時)或者下一個可讀的位置(讀buffer時)。
(3) limit:最多能寫多少數據(寫buffer時,相當于capacity),可以讀多少數據(在從通道讀入緩沖區時)。
(4) mark:標記,記錄當前position的位置,可以通過reset()恢復到mark的位置。selector的創建
Selector selector = Selector.open();
因為選擇器是用于管理通道的,因此需要將通道注冊到相應的選擇器上
channel.configureBlocking(false); //使用selector必須保證channel是非阻塞的模式
SelectionKey key = channel.register(selector, Selectionkey.OP_READ);注意register的第二個參數表示對選擇器對什么事件感興趣。
而返回值記錄了包括channel,buffer,interest集合和ready集合等。通過selector選擇通道
可以使用select()函數進行選擇,select()方法返回的int值表示有多少通道已經就緒。selectedKeys()函數
一旦調用了select()方法,并且返回值表明有一個或更多個通道就緒了,然后可以通過調用selector的selectedKeys()方法,訪問“已選擇鍵集(selected key set)”中的就緒通道。這里的selectorKey的就是之前注冊到該selector的通道。
示例程序
Selector selector = Selector.open(); //開啟選擇器 channel.configureBlocking(false); //非阻塞模式 SelectionKey key = channel.register(selector, SelectionKey.OP_READ);//注冊 while(true) { int readyChannels = selector.select(); //選擇通道 if(readyChannels == 0) continue; Set selectedKeys = selector.selectedKeys(); //獲取通道 Iterator keyIterator = selectedKeys.iterator(); while(keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if(key.isAcceptable()) { // a connection was accepted by a ServerSocketChannel. } else if (key.isConnectable()) { // a connection was established with a remote server. } else if (key.isReadable()) { // a channel is ready for reading } else if (key.isWritable()) { // a channel is ready for writing } keyIterator.remove(); //需要自己移除處理完的通道 } }六、NIO和IO的使用場景NIO具備一定的優點,但并不是說傳統IO就一無是處
(1)在處理數據上,如果遇到逐行處理的情況,如:
Name: Anna Age: 25 Email: anna@mailserver.com Phone: 1234567890傳統的IO可以這樣寫:
BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String nameLine = reader.readLine(); String ageLine = reader.readLine(); String emailLine = reader.readLine(); String phoneLine = reader.readLine();但如果使用NIO:
ByteBuffer buffer = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buffer);你就不知道緩沖區內是否剛好是一行數據,這樣處理起來會比較麻煩。
(2)如果需要管理同時打開的成千上萬個連接,這些連接每次只是發送少量的數據,例如聊天服務器,實現NIO的服務器可能是一個優勢。
如果你需要維持許多打開的連接到其他計算機上,如P2P網絡中,使用一個多帶帶的線程來管理你所有出站連接,可能是一個優勢。
但如果你有少量的連接使用非常高的帶寬,一次發送大量的數據,也許典型的IO服務器實現可能非常契合。學習參考:http://ifeve.com/java-nio-all/ Java NIO 系列教程
https://www.ibm.com/developer... NIO入門
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74999.html
摘要:是一個高性能事件驅動的異步的非堵塞的框架,用于建立等底層的連接,基于可以建立高性能的服務器。在中提供了兩套,一套是針對標準輸入輸出,另一套就是網絡編程。和是標準中的核心對象是對原中流的模擬,任何來源和目的數據都必須通過一個對象。 Netty是一個高性能 事件驅動的異步的非堵塞的IO(NIO)框架,用于建立TCP等底層的連接,基于Netty可以建立高性能的Http服務器。1、首先來復習下...
摘要:該線程在此期間不能再干任何事情了。線程通訊線程之間通過等方式通訊。選擇器傳統的模式會基于服務器會為每個客戶端請求建立一個線程由該線程單獨負貴處理一個客戶請求。 本文是對NIO知識的歸納與整理 1.阻塞與同步 1)阻塞(Block)和非租塞(NonBlock): 阻塞和非阻塞是進程在訪問數據的時候,數據是否準備就緒的一種處理方式,當數據沒有準備的時候阻塞:往往需要等待缞沖區中的數據準備好...
摘要:表示的是兩個,當其中任意一個計算完并發編程之是線程安全并且高效的,在并發編程中經常可見它的使用,在開始分析它的高并發實現機制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購,是兩個比較典型的互聯網高并發場景。 干貨:深度剖析分布式搜索引擎設計 分布式,高可用,和機器學習一樣,最近幾年被提及得最多的名詞,聽名字多牛逼,來,我們一步一步來擊破前兩個名詞,今天我們首先來說說分布式。 探究...
閱讀 1231·2021-11-25 09:43
閱讀 1342·2021-09-26 09:55
閱讀 2340·2021-09-10 11:20
閱讀 3369·2019-08-30 15:55
閱讀 1445·2019-08-29 13:58
閱讀 1171·2019-08-29 12:36
閱讀 2343·2019-08-29 11:18
閱讀 3413·2019-08-26 11:47