日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NIO 之 Selector实现原理

發布時間:2024/9/30 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NIO 之 Selector实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相關文章

NIO 之 ByteBuffer實現原理
NIO 之 Channel實現原理
NIO 之 Selector實現原理

概述

Selector允許單線程處理多個 Channel。如果你的應用打開了多個連接(通道),但每個連接的流量都很低,使用Selector就會很方便。例如,在一個聊天服務器中。

這是在一個單線程中使用一個Selector處理3個Channel的圖示:

要使用Selector,得向Selector注冊Channel,然后調用它的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒。一旦這個方法返回,線程就可以處理這些事件,事件的例子有如新連接進來,數據接收等。

Selector 作用

僅用單個線程來處理多個Channels的好處是,只需要更少的線程來處理通道。事實上,可以只用一個線程處理所有的通道。對于操作系統來說,線程之間上下文切換的開銷很大,而且每個線程都要占用系統的一些資源(如內存)。因此,使用的線程越少越好。
Selector能夠在單個線程中處理多個通道,這樣可以減少多個線程造成上下文切換問題。

Selector 源碼分析

public abstract class Selector implements Closeable {protected Selector() { }public static Selector open() throws IOException {return SelectorProvider.provider().openSelector();}public abstract boolean isOpen();public abstract SelectorProvider provider();public abstract Set<SelectionKey> keys();public abstract Set<SelectionKey> selectedKeys();public abstract int selectNow() throws IOException;public abstract int select(long timeout) throws IOException;public abstract int select() throws IOException;public abstract Selector wakeup();public abstract void close() throws IOException;

Selector 是個抽象類,提供一個靜態的方法獲取Selector子類SelectorImpl的實例。

下面分析Selector的幾個方法

register 方法

該方法是在 Channel的register方法中調用的。具體詳見NIO 之 Channel實現原理

1. 通過channel和selector構造一個SelectionKey的實例。
2. SelectionKey 注冊感興趣的事件

這四種事件用SelectionKey的四個常量來表示:
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SelectionKey.OP_READ
SelectionKey.OP_WRITE

select 方法

不同的 Channel 注冊到 Selector 后,就可以隨時查詢 Selector ,找出哪些 Channel 已經準備好可以進行處理。Channel 可能準備好上面注冊到 Selector 感興趣事件中的一個或多個。

  • select()
    獲取就緒的 Channel,阻塞方法,沒有就緒的 Channel 就一直阻塞該線程。
  • public int select() throws IOException {return select(0); }
  • select(long timeout)
    獲取就緒的 Channel, 阻塞方法,阻塞 timeout 時間,如果超時還沒有就緒的 Channel,返回0,不做任何操作。
  • public int select(long timeout)throws IOException{if (timeout < 0)throw new IllegalArgumentException("Negative timeout");return lockAndDoSelect((timeout == 0) ? -1 : timeout);}
  • selectNow()
    獲取就緒的 Channel,如果沒有就緒的就直接返回,不阻塞當前線程。
  • public int selectNow() throws IOException {return lockAndDoSelect(0);}

    上面三個 select方法底層都是調用 lockAndDoSelect 方法。
    lockAndDoSelect方法的參數值 說明:
    -1 : 一直阻塞,直到有就緒的 Channel 可處理
    0 : 不阻塞
    0: 表示阻塞多長時間

    keys 方法

    獲取所有注冊到 Selector 上的 SelectionKeypublic Set<SelectionKey> keys() {if (!isOpen() && !Util.atBugLevel("1.4")) throw new ClosedSelectorException();return publicKeys; }

    selectedKeys 方法

    獲取所有注冊到 Selector 上就緒 Channel 的 SelectionKey 信息。

    public Set<SelectionKey> selectedKeys() {if (!isOpen() && !Util.atBugLevel("1.4")) throw new ClosedSelectorException();return publicSelectedKeys; }

    SelectionKey 解析

    SelectionKey 類結構如下:

    public abstract class SelectionKey {protected SelectionKey() { }public static final int OP_READ = 1 << 0;public static final int OP_WRITE = 1 << 2;public static final int OP_CONNECT = 1 << 3;public static final int OP_ACCEPT = 1 << 4;//附件信息private volatile Object attachment = null;.... }
    • public abstract SelectableChannel channel()
      獲取channel對象
    • public abstract Selector selector()
      獲取seletor對象

    • public abstract void cancel()
      從 Selector 中取消注冊該Channel

    • public abstract int interestOps()
      獲取該chennel 注冊到 selector 上的事件

    • public abstract SelectionKey interestOps(int ops)
      修改注冊到 selector 上的事件

    • public abstract int readyOps()
      是否讀就緒

      讀就緒不等于可讀,如果沒有注冊讀事件是不能讀的。

    • public final boolean isReadable()
      判斷是否可讀

    • public final boolean isWritable()
      是否可寫

    • public final boolean isConnectable()
      是否已經連接

    • public final Object attach(Object ob)
      添加附件信息

    • public final Object attachment()
      獲取附件信息

    本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
    點擊這里快速進入簡書

    GIT地址:http://git.oschina.net/brucekankan/
    點擊這里快速進入GIT

    總結

    以上是生活随笔為你收集整理的NIO 之 Selector实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。