這篇文章主要為大家展示了“Netty對底層Selector如何優(yōu)化”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Netty對底層Selector如何優(yōu)化”這篇文章吧。
專注于為中小企業(yè)提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)雨城免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了1000多家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
在創(chuàng)建NioEventLoop時(shí)會(huì)封裝一個(gè)JDK底層的Selector屬性
private Selector selector;
那么我們簡單看一下這個(gè)Selector在JDK層面的實(shí)現(xiàn)
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);
}
}
}
從源碼中我們可以發(fā)現(xiàn), 當(dāng)服務(wù)器監(jiān)聽到事件后會(huì)封裝成SelectionKey放到HashSet中, 然后程序就可以從這個(gè)HashSet中取出事件進(jìn)行處理.
而HashSet的add方法的時(shí)間復(fù)雜度是O(n), 為此Netty通過反射機(jī)制, 將底層的這個(gè)HashSet用數(shù)組替換了, 畢竟向數(shù)組中添加數(shù)據(jù)的時(shí)間復(fù)雜度是O(1), 那么我們從代碼中找到答案吧.
NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider, SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) { selector = openSelector();}
跟進(jìn)openSelector()方法
private SelectorTuple openSelector() { final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();}
它創(chuàng)建了一個(gè)SelectedSelectionKeySet對象, 我們再看下這個(gè)類
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;
}
}
從這里我們可以發(fā)現(xiàn), 這個(gè)Set集合底層使用的是數(shù)組, 調(diào)用add方法時(shí)直接向數(shù)組中添加元素就可以, 時(shí)間復(fù)雜度O(1).
接下來看下Netty使用反射替換掉那個(gè)HashSet
Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
selectedKeysField.set(unwrappedSelector, selectedKeySet);
publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
Netty就是通過反射用這個(gè)SelectedSelectionKeySet類替換掉了Selector類中的HashSet.
這個(gè)地方之所以被Netty搞成這樣, 其實(shí)還是為了性能. 因?yàn)檫@個(gè)地方是涉及數(shù)據(jù)讀寫的源頭, 如果這個(gè)地方的性能不高, 會(huì)嚴(yán)重影響到程序的性能. 這也歸根結(jié)底回到了數(shù)據(jù)結(jié)構(gòu)的知識(shí).
以上是“Netty對底層Selector如何優(yōu)化”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!