Netty服務(wù)端啟動(dòng)-NioEventLoopGroup初始化

在使用Netty的時(shí)候,不管是客戶端還是服務(wù)端應(yīng)用,都要配置EventLoopGroup,而常用的是NioEventLoopGroup,那來看一下NioEventLoopGroup在應(yīng)用中的初始化工作。

代碼

  1. 首先新建一個(gè)NioEventLoopGroup實(shí)例。新建的時(shí)候可以指定具體的線程數(shù),如果不傳入線程的數(shù)量,線程的數(shù)量則從系統(tǒng)屬性中獲取io.netty.eventLoopThreads,如果獲取不到那么啟動(dòng)的線程數(shù)量為系統(tǒng)的cpu核數(shù)的2倍。
// 實(shí)例化
EventLoopGroup bossGroup = new NioEventLoopGroup();
...

// 默認(rèn)線程數(shù)量
DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
                "io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));
                
// 具體啟動(dòng)幾個(gè)線程
 super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);                
  1. 父類實(shí)例化的細(xì)節(jié),NioEventLoopGroup實(shí)例化的過程會(huì)不斷的實(shí)例化其父類,邏輯大都位于MultithreadEventExecutorGroup父類中,它的實(shí)例化過程如下:
  • 新建ThreadPerTaskExecutor線程執(zhí)行器,默認(rèn)的ThreadFactory為DefaultThreadFactory(getClass())
  • children未新建n個(gè)EventExecutor,如果是Nio的則為
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
        return new NioEventLoop(this, executor, (SelectorProvider) args[0],
            ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
    }
  • 將children作為參數(shù),新建EventExecutorChooser。
 public EventExecutorChooser newChooser(EventExecutor[] executors) {
        if (isPowerOfTwo(executors.length)) {
            return new PowerOfTowEventExecutorChooser(executors);
        } else {
            return new GenericEventExecutorChooser(executors);
        }
    }
  • 配置children也就是(EventExecutor)的terminationFuture監(jiān)聽器
  • 設(shè)置只讀children

以上就完成了NioEventLoopGroup的創(chuàng)建工作。

  1. 我們?cè)倏纯礃?gòu)造NioEventLoopGroup的時(shí)候一些其他配置。
  • ThreadPerTaskExecutor,其作用就是調(diào)用threadFactory新建一個(gè)線程,然后執(zhí)行。
public final class ThreadPerTaskExecutor implements Executor {
    private final ThreadFactory threadFactory;

    public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
        if (threadFactory == null) {
            throw new NullPointerException("threadFactory");
        }
        this.threadFactory = threadFactory;
    }

    @Override
    public void execute(Runnable command) {
        threadFactory.newThread(command).start();
    }
}
  • DefaultThreadFactory的新建線程,同時(shí)配置線程為daemon和線程優(yōu)先級(jí)。
@Override
    public Thread newThread(Runnable r) {
        Thread t = newThread(new DefaultRunnableDecorator(r), prefix + nextId.incrementAndGet());
        try {
            if (t.isDaemon()) {
                if (!daemon) {
                    t.setDaemon(false);
                }
            } else {
                if (daemon) {
                    t.setDaemon(true);
                }
            }

            if (t.getPriority() != priority) {
                t.setPriority(priority);
            }
        } catch (Exception ignored) {
            // Doesn't matter even if failed to set.
        }
        return t;
    }

    protected Thread newThread(Runnable r, String name) {
        return new FastThreadLocalThread(threadGroup, r, name);
    }
  • 線程選擇器,DefaultEventExecutorChooserFactory,內(nèi)部也比較明確,其主要就是從EventExecutor中按一定的規(guī)則選擇一個(gè)執(zhí)行線程。
  • 最終的EventExecutor為NioEventLoop

最后

這次看了NioEventLoopGroup的構(gòu)建工作

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容