Netty对底层Selector如何优化

这篇文章主要为大家展示了“Netty对底层Selector如何优化”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Netty对底层Selector如何优化”这篇文章吧。

专注于为中小企业提供网站设计、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业雨城免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了1000多家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

在创建NioEventLoop时会封装一个JDK底层的Selector属性

private Selector selector;

那么我们简单看一下这个Selector在JDK层面的实现

public abstract class SelectorImpl extends AbstractSelector {    protected Set selectedKeys = new HashSet();    protected HashSet keys = new HashSet();    private Set publicKeys;    private Set publicSelectedKeys;

   protected SelectorImpl(SelectorProvider var1) {        super(var1);        if (Util.atBugLevel("1.4")) {            this.publicKeys = this.keys;            this.publicSelectedKeys = this.selectedKeys;        } else {            this.publicKeys = Collections.unmodifiableSet(this.keys);            this.publicSelectedKeys = Util.ungrowableSet(this.selectedKeys);        }    }}

从源码中我们可以发现, 当服务器监听到事件后会封装成SelectionKey放到HashSet中, 然后程序就可以从这个HashSet中取出事件进行处理.

而HashSet的add方法的时间复杂度是O(n), 为此Netty通过反射机制, 将底层的这个HashSet用数组替换了, 毕竟向数组中添加数据的时间复杂度是O(1), 那么我们从代码中找到答案吧.

NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,                 SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {            selector = openSelector();}

跟进openSelector()方法

private SelectorTuple openSelector() {  final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();}

它创建了一个SelectedSelectionKeySet对象, 我们再看下这个类

final class SelectedSelectionKeySet extends AbstractSet {

   SelectionKey[] keys;    int size;

   SelectedSelectionKeySet() {        keys = new SelectionKey[1024];    }

   @Override    public boolean add(SelectionKey o) {        if (o == null) {            return false;        }

       keys[size++] = o;        if (size == keys.length) {            increaseCapacity();        }

       return true;    }}

从这里我们可以发现, 这个Set集合底层使用的是数组, 调用add方法时直接向数组中添加元素就可以, 时间复杂度O(1).

接下来看下Netty使用反射替换掉那个HashSet

Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");          
selectedKeysField.set(unwrappedSelector, selectedKeySet);publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);

Netty就是通过反射用这个SelectedSelectionKeySet类替换掉了Selector类中的HashSet. 

这个地方之所以被Netty搞成这样, 其实还是为了性能. 因为这个地方是涉及数据读写的源头, 如果这个地方的性能不高, 会严重影响到程序的性能. 这也归根结底回到了数据结构的知识.

以上是“Netty对底层Selector如何优化”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!


网站名称:Netty对底层Selector如何优化
本文路径:http://azwzsj.com/article/gsoedp.html