<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## Java專題十一(2):NIO [TOC] ### 0. NIO是什么 Non-blocking IO(非阻塞IO) > NIO可以讓你非阻塞的使用IO,當線程從通道讀取數據到緩沖區時,線程還是可以進行其他事情。當數據被寫入到緩沖區時,線程可以繼續處理它。從緩沖區寫入通道也類似。 ### 1. 通道Channel > 通道代表面向實體的開放式連接,執行讀寫等IO操作,其中實體包括硬件設備,文件,網絡套接字等 通道`Channel`與緩沖區`Buffer`密不可分,不同于IO從字符或字節流中讀寫操作,`Channel`既可以從`Buffer`中讀取數據,也可以寫入數據到`Buffer`中 **類圖關系如下**: - Channel - InterruptibleChannel - FileChannel - SelectableChannel:能與選擇器`Selector`結合實現多路IO復用 - SocketChannel - ServerSocketChannel - DatagramChannel - ReadableByteChannel:讀取Channel數據到Buffer中, `int read(ByteBuffer dst)` - WritableByteChannel:寫入Buffer數據到Channel中,` int write(ByteBuffer src)` `Channel`中一些重要方法: | 方法 | 說明 | | --- | --- | | `open()` | 用于創建Channel對象,如`ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();` | | `SelectionKey register(Selector sel, int ops)` | 只適用于`SelectableChannel`類型的通道,用于向Selector中注冊操作,當通道中有注冊過的操作時,可以對通道進行操作。ops包括4種: `SelectionKey.OP_ACCEPT`/`SelectionKey.OP_CONNECT`/`SelectionKey.OP_READ`/`SelectionKey.OP_WRITE` | | `SelectableChannel configureBlocking(boolean block)` | 只適用于`SelectableChannel`類型的通道,用于配置是否阻塞模式,如`serverSocketChannel.configureBlocking(false);` | | `int read(ByteBuffer dst)` | 將Channel里的數據讀取到Buffer中 | | `int write(ByteBuffer src)` | 將Buffer中的數據寫入到Channel中 | ### 2. 緩沖區Buffer > 相當于內存塊,可讀可寫 **類圖關系如下**: - Buffer - ByteBuffer: - HeapByteBuffer - CharBuffer: - ShortBuffer: - IntBuffer: - LongBuffer: - FloatBuffer: - DoubleBuffer: - DirectBuffer - DirectByteBuffer `ByteBuffer`中一些重要方法: | 方法 | 說明 | | --- | --- | | `allocate(int capacity)` | 用于創建容量為capacity的Buffer對象,如`ByteBuffer buffer = ByteBuffer.allocate(1024);` | | `boolean hasRemaining()` | 是否有元素在`position`和`limit`之間| | `ByteBuffer put(byte b)` | 將一個字節寫入Buffer中 | | `ByteBuffer put(byte[] src)` | 將字節數組寫入Buffer中 | | `byte get()` | 從Buffer中獲取一個字節 | | `byte get(byte[] dst)` | 將Buffer中數據寫入字節數組中 | | `ByteBuffer flip()` | 從寫模式切換為讀模式,`limit = positon; positon = 0; mark = -1` | | `ByteBuffer rewind()` | `position = 0; mark = -1;` | | `ByteBuffer clear()` | `position = 0; limit = capacity; mark = -1;` | | `ByteBuffer reset()` | `position = mark;` | `capacity`、`position`、`limit`說明: - capacity:緩沖區的大小,最多可以存放capacity個數據 - position:寫模式下,代表寫入了多少個數據,使用`flip()`切換為讀模式時,position設為0 - limit:讀模式下,代表能讀取到的數據大小,使用`flip()`切換為讀模式時,limit設為position ### 3. 選擇器Selector > 一個`Selector`可以處理多個`Channel`,通常與`SelectableChannel`類型的`Channel`結合使用 `Selector`中一些重要方法: | 方法 | 說明 | | --- | --- | | `Selector open()` | 用于創建一個Selector對象,如`Selector selector = Selector.open();`| | `int select()` | 選擇ready狀態的操作集(keys set)| | `Set<SelectionKey> selectedKeys()` | 獲取選擇器已經選擇的操作集(keys set)| ### 4.一個完整示例 ~~~ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class Server { public static void main(String[] args) throws Exception{ ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8017)); Selector selector = Selector.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while(true){ selector.select(); Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while(iterator.hasNext()){ SelectionKey key = iterator.next(); if(key.isAcceptable()){ System.out.println("key.isAcceptable()"); iterator.remove(); SocketChannel socketChannel = ((ServerSocketChannel)key.channel()).accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); }else if(key.isReadable()){ System.out.println("key.isReadable()"); iterator.remove(); SocketChannel socketChannel = (SocketChannel)key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); socketChannel.read(buffer); System.out.println(new String(buffer.array())); socketChannel.register(selector, SelectionKey.OP_WRITE); }else if(key.isWritable()){ System.out.println("key.isWritable()"); iterator.remove(); SocketChannel socketChannel = (SocketChannel)key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); buffer.put(new String("i am server!!!").getBytes()); socketChannel.write(buffer); System.out.println(new String(buffer.array())); socketChannel.register(selector, SelectionKey.OP_READ); } } } } } ~~~ 1. 運行Server.java 2. 在CMD命令行輸入`telnet 127.0.0.1 8017 `,換行,輸入ab 3. 控制臺輸出如下: ~~~ key.isAcceptable() key.isReadable() a key.isWritable() i am server!!! key.isReadable() b key.isWritable() i am server!!! ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看