欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Netty分布式NioEventLoop優(yōu)化selector源碼解析

 更新時(shí)間:2022年03月25日 13:12:40   作者:向南是個(gè)萬(wàn)人迷  
這篇文章主要介紹了Netty分布式NioEventLoop優(yōu)化selector源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

優(yōu)化selector

selector的創(chuàng)建過(guò)程

在剖析selector輪詢(xún)之前, 我們先講解一下selector的創(chuàng)建過(guò)程

回顧之前的小節(jié), 在創(chuàng)建NioEventLoop中初始化了唯一綁定的selector:

NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider, 
             SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {
    super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler);
    //代碼省略
    provider = selectorProvider;
    selector = openSelector();
    selectStrategy = strategy;
}

這里 selector = openSelector() 初始化了selector

我們跟到openSelector()中:

private Selector openSelector() {
    final Selector selector;
    try {
        //調(diào)用jdk底層的api
        selector = provider.openSelector();
    } catch (IOException e) {
        throw new ChannelException("failed to open a new selector", e);
    }
    //判斷是否需要關(guān)閉優(yōu)化(默認(rèn)false, 也就是默認(rèn)需要優(yōu)化)
    if (DISABLE_KEYSET_OPTIMIZATION) {
        return selector;
    }
    //用這個(gè)數(shù)據(jù)結(jié)構(gòu)替換原生的SelectionKeySet
    final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
    Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
        @Override
        public Object run() {
            try {
                //通過(guò)反射拿到sun.nio.ch.SelectorImpl這個(gè)類(lèi)的class對(duì)象
                return Class.forName("sun.nio.ch.SelectorImpl", false, PlatformDependent.getSystemClassLoader());
            } catch (ClassNotFoundException e) {
                return e;
            } catch (SecurityException e) {
                return e;
            }
        }
    });
    //判斷拿到的是不是class對(duì)象并且是不是Selector的實(shí)現(xiàn)類(lèi)
    if (!(maybeSelectorImplClass instanceof Class) ||!((Class<?>) maybeSelectorImplClass).isAssignableFrom(selector.getClass())) {
        if (maybeSelectorImplClass instanceof Exception) {
            Exception e = (Exception) maybeSelectorImplClass;
            logger.trace("failed to instrument a special java.util.Set into: {}", selector, e);
        }
        //如果不是他的實(shí)現(xiàn), 就直接返回原生select
        return selector;
    }
    //如果是它的實(shí)現(xiàn), 就拿到其class對(duì)象
    final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
    Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
        @Override
        public Object run() {
            try {
                //通過(guò)反射拿到selectedKeys和publicSelectedKeys兩個(gè)屬性, 默認(rèn)這兩個(gè)屬性底層都是hashSet方式實(shí)現(xiàn)的
                Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
                Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
                //設(shè)置成可修改的
                selectedKeysField.setAccessible(true);
                publicSelectedKeysField.setAccessible(true);
                //將selector的這兩個(gè)屬性替換成Netty的selectedKeySet
                selectedKeysField.set(selector, selectedKeySet);
                publicSelectedKeysField.set(selector, selectedKeySet);
                return null;
            } catch (NoSuchFieldException e) {
                return e;
            } catch (IllegalAccessException e) {
                return e;
            } catch (RuntimeException e) {
                if ("java.lang.reflect.InaccessibleObjectException".equals(e.getClass().getName())) {
                    return e;
                } else {
                    throw e;
                }
            }
        }
    });
    if (maybeException instanceof Exception) {
        selectedKeys = null;
        Exception e = (Exception) maybeException;
        logger.trace("failed to instrument a special java.util.Set into: {}", selector, e);
    } else {
        //將優(yōu)化后的keySet保存成NioEventLoop的成員變量
        selectedKeys = selectedKeySet;
        logger.trace("instrumented a special java.util.Set into: {}", selector);
    }
    return selector;
}

代碼剖析

這里代碼比較長(zhǎng), 我們一點(diǎn)一點(diǎn)的剖析:

首先 selector = provider.openSelector() 這里創(chuàng)建了jdk底層的selector

if (DISABLE_KEYSET_OPTIMIZATION) {
    return selector;
}

這里判斷了是否關(guān)閉優(yōu)化功能, 默認(rèn)是false, 也就是需要優(yōu)化, 這里的意思就是netty需要對(duì)jdk原生的selector進(jìn)行了優(yōu)化, 我們知道selector在select()操作時(shí)候, 會(huì)通過(guò)selector.selectedKeys()操作返回一個(gè)Set<SelectionKey>, 這個(gè)是Set類(lèi)型, netty對(duì)這個(gè)set進(jìn)行了處理, 使用SelectedSelectionKeySet的數(shù)據(jù)結(jié)構(gòu)進(jìn)行替換, 當(dāng)在select()操作時(shí)將key存入一個(gè)SelectedSelectionKeySet的數(shù)據(jù)結(jié)構(gòu)中

final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();

這里一步創(chuàng)建了這個(gè)優(yōu)化后的數(shù)據(jù)結(jié)構(gòu)

簡(jiǎn)單跟一下SelectedSelectctionKeySet這個(gè)類(lèi)的構(gòu)造方法:

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

初始化了兩個(gè)屬性keysA和keysB, 說(shuō)明這類(lèi)其實(shí)底層是通過(guò)數(shù)組實(shí)現(xiàn)的, 通過(guò)操作數(shù)組下標(biāo)會(huì)有更高的效率

這個(gè)類(lèi)的的flip()方法, 則返SelectionKey[]數(shù)組

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 boolean remove(Object o) {
    return false;
}
@Override
public boolean contains(Object o) {
    return false;
}
@Override
public Iterator<SelectionKey> iterator() {
    throw new UnsupportedOperationException();
}

我們看到remove()方法, contains()方法都返回了false, 說(shuō)明其不支持刪除方法和包含方法, iterator()方法則直接拋出異常, 說(shuō)明其不支持迭代器操作

回到openSelector()中:

再往下看, 這里通過(guò) Class.forName("sun.nio.ch.SelectorImpl", false, PlatformDependent.getSystemClassLoader()) 創(chuàng)建了一個(gè)SelectorImpl的class對(duì)象

 if(!(maybeSelectorImplClass instanceof Class) ||!((Class<?>) maybeSelectorImplClass).isAssignableFrom(selector.getClass())) 

這里判斷拿到的對(duì)象是否為class對(duì)象并且是否為Selector的實(shí)現(xiàn)類(lèi), 如果不是, 則直接返回jdk的selector

如果是, 就繼續(xù)轉(zhuǎn)化成class對(duì)象

然后就做了真正的替換操作:

//通過(guò)反射拿到selectedKeys和publicSelectedKeys兩個(gè)屬性, 默認(rèn)這兩個(gè)屬性底層都是hashSet方式實(shí)現(xiàn)的
Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
//設(shè)置成可修改的
selectedKeysField.setAccessible(true);
publicSelectedKeysField.setAccessible(true);
//將selector的這兩個(gè)屬性替換成Netty的selectedKeySet
selectedKeysField.set(selector, selectedKeySet);
publicSelectedKeysField.set(selector, selectedKeySet);

通過(guò)注釋我們不難看出, 這里將新創(chuàng)建selectedKeySet替換了selector對(duì)象中的selectedKeysField, 和selectedKeysField兩個(gè)屬性

最后通過(guò) selectedKeys = selectedKeySet 將優(yōu)化的數(shù)據(jù)結(jié)構(gòu)selectedKeySet保存在NioEventLoop的成員變量中

最后返回優(yōu)化后的selector

這樣, selector在select()操作的過(guò)程中, 如果有就緒事件則會(huì)將返回的key存放在selectedKeySet所對(duì)應(yīng)的數(shù)組中

以上就是Netty分布式NioEventLoop優(yōu)化selector源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Netty分布式NioEventLoop優(yōu)化selector的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java實(shí)現(xiàn)打印正三角的方法

    java實(shí)現(xiàn)打印正三角的方法

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)打印正三角的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • java?fastjson傳輸long數(shù)據(jù)卻接收到了int的問(wèn)題

    java?fastjson傳輸long數(shù)據(jù)卻接收到了int的問(wèn)題

    這篇文章主要介紹了java?fastjson傳輸long數(shù)據(jù)卻接收到了int的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 詳解Java的Enum的使用與分析

    詳解Java的Enum的使用與分析

    這篇文章主要介紹了詳解Java的Enum的使用與分析的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 詳解Java數(shù)據(jù)結(jié)構(gòu)之平衡二叉樹(shù)

    詳解Java數(shù)據(jù)結(jié)構(gòu)之平衡二叉樹(shù)

    平衡二叉樹(shù)(Balanced?Binary?Tree)又被稱(chēng)為AVL樹(shù)(有別于AVL算法),且具有以下性質(zhì):它是一?棵空樹(shù)或它的左右兩個(gè)子樹(shù)的高度差的絕對(duì)值不超過(guò)1,并且左右兩個(gè)子樹(shù)都是一棵平衡二叉樹(shù)。本文將詳解介紹一下平衡二叉樹(shù)的原理與實(shí)現(xiàn),需要的可以參考一下
    2022-02-02
  • Java開(kāi)發(fā)之手把手教你搭建企業(yè)級(jí)工程SSM框架

    Java開(kāi)發(fā)之手把手教你搭建企業(yè)級(jí)工程SSM框架

    這篇文章主要為大家介紹Java教程中搭建企業(yè)級(jí)工程SSM框架,手把手的過(guò)程操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • 關(guān)于mybatis callSettersOnNulls 配置解析

    關(guān)于mybatis callSettersOnNulls 配置解析

    這篇文章主要介紹了關(guān)于mybatis callSettersOnNulls 配置,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2018-06-06
  • 使用SpringBoot中整合Redis

    使用SpringBoot中整合Redis

    這篇文章主要介紹了使用SpringBoot中整合Redis,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Gradle的使用教程詳解

    Gradle的使用教程詳解

    Gradle它使用一種基于Groovy的特定領(lǐng)域語(yǔ)言(DSL)來(lái)聲明項(xiàng)目設(shè)置,目前也增加了基于Kotlin語(yǔ)言的kotlin-based DSL,拋棄了基于XML的各種繁瑣配置,下面通過(guò)本文給大家介紹Gradle的使用教程,感興趣的朋友一起看看吧
    2020-09-09
  • java多線(xiàn)程編程之使用Synchronized塊同步方法

    java多線(xiàn)程編程之使用Synchronized塊同步方法

    synchronized塊來(lái)同步一個(gè)對(duì)象變量,也可以使用synchronized塊來(lái)同步類(lèi)中的靜態(tài)方法和非靜態(tài)方法,下面使用Synchronized塊同步方法
    2014-01-01
  • springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext問(wèn)題

    springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext問(wèn)題

    這篇文章主要介紹了springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評(píng)論