根據(jù)我們前面分析的,接收到消息后,為了避免在I/O線程里執(zhí)行耗時的操作,一般都會使用線程池來執(zhí)行業(yè)務(wù)處理邏輯.
那是使用Netty提供給我們的方法,傳入一個線程池還是使用我們自己定義的線程池好呢?
先來看Netty給我們提供的
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
即我們添加handler的時候可以傳入一個線程池進去
DefaultEventExecutorGroup
它與NioEventLoop之間的區(qū)別又是什么?
NioEventLoop
側(cè)重于處理網(wǎng)絡(luò)I/O相關(guān)的各種事件,例如連接操作,消息讀取和發(fā)送操作
DefaultEventExecutor
側(cè)重于處理業(yè)務(wù)相關(guān)的邏輯,將業(yè)務(wù)的ChannelHandler與具體的DefaultEventExecutor綁定起來.

其次
對于某個客戶端連接Channel,只會注冊到一個NioEventLoop線程中,用于處理網(wǎng)絡(luò)I/O操作,業(yè)務(wù)的ChannelHandler指定了運行線程池EventLoopGroup之后,創(chuàng)建ChannelHandlerContext上下文時會從EventLoopGroup中選擇一個EventExecutor綁定到該Channel對應(yīng)的ChannelHandler實例.
也就是說使用netty提供默認的,是綁定的.如下圖

使用我們自己定義的線程池

雖然LinkedBlockQueue通過讀寫鎖來提升性能,但是當(dāng)業(yè)務(wù)線程數(shù)和寫操作比較多時,鎖競爭對性能的影響還是比較大的。
如果采用自定義線程池時,優(yōu)化方向就是鎖消除.
可以使用Disruptor或者使用ChannelId與業(yè)務(wù)線程池中的某個業(yè)務(wù)進行綁定