最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

優(yōu)化selector

selector的創(chuàng)建過程

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

回顧之前的小節(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 {
        //調用jdk底層的api
        selector = provider.openSelector();
    } catch (IOException e) {
        throw new ChannelException("failed to open a new selector", e);
    }
    //判斷是否需要關閉優(yōu)化(默認false, 也就是默認需要優(yōu)化)
    if (DISABLE_KEYSET_OPTIMIZATION) {
        return selector;
    }
    //用這個數據結構替換原生的SelectionKeySet
    final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
    Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
        @Override
        public Object run() {
            try {
                //通過反射拿到sun.nio.ch.SelectorImpl這個類的class對象
                return Class.forName("sun.nio.ch.SelectorImpl", false, PlatformDependent.getSystemClassLoader());
            } catch (ClassNotFoundException e) {
                return e;
            } catch (SecurityException e) {
                return e;
            }
        }
    });
    //判斷拿到的是不是class對象并且是不是Selector的實現類
    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);
        }
        //如果不是他的實現, 就直接返回原生select
        return selector;
    }
    //如果是它的實現, 就拿到其class對象
    final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
    Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
        @Override
        public Object run() {
            try {
                //通過反射拿到selectedKeys和publicSelectedKeys兩個屬性, 默認這兩個屬性底層都是hashSet方式實現的
                Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
                Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
                //設置成可修改的
                selectedKeysField.setAccessible(true);
                publicSelectedKeysField.setAccessible(true);
                //將selector的這兩個屬性替換成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;
}

代碼剖析

這里代碼比較長, 我們一點一點的剖析:

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

if (DISABLE_KEYSET_OPTIMIZATION) {
    return selector;
}

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

final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();

這里一步創(chuàng)建了這個優(yōu)化后的數據結構

簡單跟一下SelectedSelectctionKeySet這個類的構造方法:

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

初始化了兩個屬性keysA和keysB, 說明這類其實底層是通過數組實現的, 通過操作數組下標會有更高的效率

這個類的的flip()方法, 則返SelectionKey[]數組

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, 說明其不支持刪除方法和包含方法, iterator()方法則直接拋出異常, 說明其不支持迭代器操作

回到openSelector()中:

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

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

這里判斷拿到的對象是否為class對象并且是否為Selector的實現類, 如果不是, 則直接返回jdk的selector

如果是, 就繼續(xù)轉化成class對象

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

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

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

最后通過 selectedKeys = selectedKeySet 將優(yōu)化的數據結構selectedKeySet保存在NioEventLoop的成員變量中

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

這樣, selector在select()操作的過程中, 如果有就緒事件則會將返回的key存放在selectedKeySet所對應的數組中

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

相關文章

  • org.apache.ibatis.annotations不存在的問題

    org.apache.ibatis.annotations不存在的問題

    這篇文章主要介紹了org.apache.ibatis.annotations不存在的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • springboot統(tǒng)一異常處理(返回json)并格式化異常

    springboot統(tǒng)一異常處理(返回json)并格式化異常

    這篇文章主要介紹了springboot統(tǒng)一異常處理(返回json)并格式化異常,對spring boot的默認異常處理方式進行修改,要統(tǒng)一返回數據格式,優(yōu)雅的數據交互,優(yōu)雅的開發(fā)應用,需要的朋友可以參考下
    2023-07-07
  • SpringCloud中的Consul詳解

    SpringCloud中的Consul詳解

    這篇文章主要介紹了SpringCloud中的Consul知識,本文使用的是docker-compose方式管理consul服務,直接啟動即可,需要的朋友可以參考下
    2022-03-03
  • 使用springboot 獲取控制器參數的幾種方法小結

    使用springboot 獲取控制器參數的幾種方法小結

    這篇文章主要介紹了使用springboot 獲取控制器參數的幾種方法小結,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 手把手教你idea中創(chuàng)建一個javaweb(webapp)項目詳細圖文教程

    手把手教你idea中創(chuàng)建一個javaweb(webapp)項目詳細圖文教程

    這篇文章主要介紹了如何使用IntelliJ?IDEA創(chuàng)建一個Maven項目,并配置Tomcat服務器進行運行,過程包括創(chuàng)建項目、配置運行環(huán)境、部署項目以及測試運行,需要的朋友可以參考下
    2025-01-01
  • MapReduce核心思想圖文詳解

    MapReduce核心思想圖文詳解

    今天小編就為大家分享一篇關于MapReduce核心思想圖文詳解,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 判斷List和Map是否相等并合并List中相同的Map

    判斷List和Map是否相等并合并List中相同的Map

    今天小編就為大家分享一篇關于判斷List和Map是否相等并合并List中相同的Map,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 詳解Java8新特性如何防止空指針異常

    詳解Java8新特性如何防止空指針異常

    要說 Java 編程中哪個異常是你印象最深刻的,那 NullPointerException 空指針可以說是臭名昭著的,不要說初級程序員會碰到, 即使是中級,專家級程序員稍不留神,就會掉入這個坑里,本文就和大家聊聊Java8新特性如何防止空指針異常
    2023-08-08
  • java日期相關類實例詳解

    java日期相關類實例詳解

    這篇文章主要介紹了java日期相關類實例詳解,小編覺得還是挺不錯的,這里分享給大家,供需要的朋友參考。
    2017-10-10
  • springboot2中session超時,退到登錄頁面方式

    springboot2中session超時,退到登錄頁面方式

    這篇文章主要介紹了springboot2中session超時,退到登錄頁面方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論

宝山区| 南充市| 玉环县| 甘孜县| 溧水县| 虹口区| 南康市| 德钦县| 阿拉善盟| 时尚| 河源市| 富蕴县| 家居| 兰溪市| 剑阁县| 克拉玛依市| 武宣县| 广南县| 嘉峪关市| 凌海市| 泰兴市| 漠河县| 松滋市| 湖南省| 乌什县| 邢台县| 长泰县| 河源市| 瓦房店市| 望城县| 陈巴尔虎旗| 延津县| 临沭县| 庆安县| 锡林郭勒盟| 松潘县| 弥勒县| 嘉善县| 柳河县| 西盟| 东丽区|