<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在剖析selector輪詢之前, 我們先講解一下selector的建立過程
回顧之前的小節, 在建立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); } //判斷是否需要關閉優化(預設false, 也就是預設需要優化) 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 { //將優化後的keySet儲存成NioEventLoop的成員變數 selectedKeys = selectedKeySet; logger.trace("instrumented a special java.util.Set into: {}", selector); } return selector; }
這裡程式碼比較長, 我們一點一點的剖析:
首先 selector = provider.openSelector() 這裡建立了jdk底層的selector
if (DISABLE_KEYSET_OPTIMIZATION) { return selector; }
這裡判斷了是否關閉優化功能, 預設是false, 也就是需要優化, 這裡的意思就是netty需要對jdk原生的selector進行了優化, 我們知道selector在select()操作時候, 會通過selector.selectedKeys()操作返回一個Set<SelectionKey>, 這個是Set型別, netty對這個set進行了處理, 使用SelectedSelectionKeySet的資料結構進行替換, 當在select()操作時將key存入一個SelectedSelectionKeySet的資料結構中
final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
簡單跟一下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()) 建立了一個SelectorImpl的class物件
if(!(maybeSelectorImplClass instanceof Class) ||!((Class<?>) maybeSelectorImplClass).isAssignableFrom(selector.getClass()))
這裡判斷拿到的物件是否為class物件並且是否為Selector的實現類, 如果不是, 則直接返回jdk的selector
如果是, 就繼續轉化成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);
通過註釋我們不難看出, 這裡將新建立selectedKeySet替換了selector物件中的selectedKeysField, 和selectedKeysField兩個屬性
最後通過 selectedKeys = selectedKeySet 將優化的資料結構selectedKeySet儲存在NioEventLoop的成員變數中
這樣, selector在select()操作的過程中, 如果有就緒事件則會將返回的key存放在selectedKeySet所對應的陣列中
以上就是Netty分散式NioEventLoop優化selector原始碼解析的詳細內容,更多關於Netty分散式NioEventLoop優化selector的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45