咱們看看ReadTimeoutHandler下面這個初始化方法,在初始化的時候作的一些事情,Netty的2個改進點我認爲都在這裏能夠體現出來(下面紅體):git
private void initialize(ChannelHandlerContext ctx) {github
// Avoid the case where destroy() is called before scheduling timeouts.異步
// See: https://github.com/netty/netty/issues/143oop
switch (state) {spa
case 1:操作系統
case 2:netty
return;資源
}it
state = 1;io
lastReadTime = System.currentTimeMillis();
if (timeoutMillis > 0) {
timeout = ctx.executor().schedule(
new ReadTimeoutTask(ctx),
timeoutMillis, TimeUnit.MILLISECONDS);
}
}
一個過於頻繁的調用System.currentTimeMillis();這個調用要從操做系統取得超時時間,這個是須要消耗必定資源的。然而咱們能夠看到這個類裏面,該方法被反覆的調用。假若有10000個channel,那麼就有10000個這個handler,System.currentTimeMillis();被調用的頻率就會很是高,而這麼高的調用頻率實際上是沒什麼意義的。兩次調用之間可能相差連1ms都不到,請問在這種狀況下,如此精確意義何在呢?
更好的作法多是在主循環裏面取得一次時間,而後在全部handler裏面用同一個時間。(關於主循環的位置後面再說)
另一處就是這個ctx.executor().schedule方法的調用了,爲了處理channel過時,咱們往主循環裏面提交了一個過時處理任務(關於主循環的位置後面再說),一樣,若是1萬個channel,那麼就有1萬個runnable被執行。這裏一樣,若是在1個runnable裏面處理這1萬個channel是否效率會更高?
主循環就是NioEventLoop的run方法,這裏是,讀,flush全部異步IO操做的發起點。
咱們能夠在run方法裏面獲取1個系統時間,而後在後面的handler裏面統一使用這個NioEventLoop級別的時間。
一樣,咱們也能夠在NioEventLoop裏面維護一個過時任務,處理全部的channel。
綜上,因爲netty裏面把過時處理放到了channel hanlder級別,而不是nioeventloop級別,致使效率上值得商榷。