netty:SelectedSelectionKeySet介绍

介绍

SelectedSelectionKeySet用来代替Selector的selectedKeys成员和publicSelectedKeys成员,提高性能

实现

我们先来看下成员

    private SelectionKey[] keysA;
    private int keysASize;
    private SelectionKey[] keysB;
    private int keysBSize;
    private boolean isA = true;

里面通过两个数组和一个标示来进行切换的。

  SelectedSelectionKeySet() {
        keysA = new SelectionKey[1024];
        keysB = keysA.clone();
    }

构造函数中,默认给两个数组都分配了1024个空间

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

        if (isA) {
            int size = keysASize;
            keysA[size ++] = o;
            keysASize = size;
            if (size == keysA.length) {
                doubleCapacityA();
            }
        } else {
            int size = keysBSize;
            keysB[size ++] = o;
            keysBSize = size;
            if (size == keysB.length) {
                doubleCapacityB();
            }
        }

        return true;
    }

这个添加一个元素,从代码中可以看出,首先是需要看现在在那个数组中操作,往对应的数组末尾加个元素,增加下标,最后看数组是否满了,如果满了就进行数组的扩大

 private void doubleCapacityA() {
        SelectionKey[] newKeysA = new SelectionKey[keysA.length << 1];
        System.arraycopy(keysA, 0, newKeysA, 0, keysASize);
        keysA = newKeysA;
    }

申请两倍的空间,在把原来的内容复制到新的空间。
我们在来看下个成员flip(),他主要用来获取现有的元素,并进行切换

  SelectionKey[] flip() {
        if (isA) {
            isA = false;
            keysA[keysASize] = null;
            keysBSize = 0;
            return keysA;
        } else {
            isA = true;
            keysB[keysBSize] = null;
            keysASize = 0;
            return keysB;
        }
    }

最后还有几个函数都比较简单

   @Override
    public int size() {
        if (isA) {
            return keysASize;
        } else {
            return keysBSize;
        }
    }

    @Override
    public boolean remove(Object o) {
        return false;
    }

    @Override
    public boolean contains(Object o) {
        return false;
    }

    @Override
    public Iterator<SelectionKey> iterator() {
        throw new UnsupportedOperationException();
    }

使用

在NioEventLoop类中的openSelector函数中

 private Selector openSelector() {
        final Selector selector;
        try {
            selector = provider.openSelector();
        } catch (IOException e) {
            throw new ChannelException("failed to open a new selector", e);
        }

        if (DISABLE_KEYSET_OPTIMIZATION) {
            return selector;
        }

        try {
            SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();

            Class<?> selectorImplClass =
                    Class.forName("sun.nio.ch.SelectorImpl", false, PlatformDependent.getSystemClassLoader());

            // Ensure the current selector implementation is what we can instrument.
            if (!selectorImplClass.isAssignableFrom(selector.getClass())) {
                return selector;
            }

            Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
            Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");

            selectedKeysField.setAccessible(true);
            publicSelectedKeysField.setAccessible(true);

            selectedKeysField.set(selector, selectedKeySet);
            publicSelectedKeysField.set(selector, selectedKeySet);

            selectedKeys = selectedKeySet;
            logger.trace("Instrumented an optimized java.util.Set into: {}", selector);
        } catch (Throwable t) {
            selectedKeys = null;
            logger.trace("Failed to instrument an optimized java.util.Set into: {}", selector, t);
        }

        return selector;
    }

首先创建了一个selector和自定义的selectedKeySet,然后通过反射的机制,把selector中的两个成员: selectedKeys和publicSelectedKeys使用我们自定义的那selectKeySet代替

原理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,544评论 1 51
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 1,205评论 0 1
  • 夏末秋色未见,梧桐绿叶兼细雨 廊上凉风起,倚栏听笛,别有一番新意 沁人夜色,忽勾念,垂髻之年,折柳绕桂冠 莹莹火虫...
    落英冰封阅读 442评论 4 6
  • 我是一个很少记得梦的人。临晨从一个梦突然醒来:梦里发现我们埋在一个子弹头一样的巨大无比的金属壳中,说是今后数百年...
    周章阅读 243评论 0 0
  • 文/孤鸟差鱼 又在企图讨伐 不该你的
    孤鸟差鱼阅读 179评论 1 4