【Netty源码分析】 客户端接入流程

Netty服务端启动完成,这时候客户端连接就可以接入进来了,下面我们就来分析下客户端连接接入的流程。

之前分析过NioEventLoop线程启动方法是startThread(),由于这个方法里面的逻辑比较复杂,并没有展开,这一节就是从这个方法开始分析。

startThread

private void startThread() {
    if (state == ST_NOT_STARTED) {
        if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {
            try {
                doStartThread();
            } catch (Throwable cause) {
                STATE_UPDATER.set(this, ST_NOT_STARTED);
                PlatformDependent.throwException(cause);
            }
        }
    }
}

这个方法主要主要完成2件事:

  • 利用casNioEventLoop的状态由ST_NOT_STARTED修改成ST_STARTED,即表示NioEventLoop线程启动;

  • 执行doStartThread()方法;

doStartThread()方法看着比较复杂,核心逻辑如下,向线程池执行器executor提交一个任务,而这个线程池执行器类型是ThreadPerTaskExecutor,即每次执行任务都会创建一个新线程,而且这个任务是无限循环的:事件轮询selector.select()、事件处理processSelectedKeys()和任务队列处理runAllTasks(),这样NioEventLoop就和具体的Thread线程进行了关联:

private void doStartThread() {
    assert thread == null;
    //executor线程执行器,类型是:ThreadPerTaskExecutor,即每次执行任务都会创建一个新线程
    executor.execute(new Runnable() {
        @Override
        public void run() {
            //将executor线程执行器创建的线程:FastThreadLocalThread保存到EventLoop的全局变量中,相当于thread和EventLoop的绑定
            thread = Thread.currentThread();
            if (interrupted) {
                thread.interrupt();
            }

            boolean success = false;
            updateLastExecutionTime();
            try {
                //然后调用EventLoop中的run方法进行启动
                SingleThreadEventExecutor.this.run();
                success = true;
            } catch (Throwable t) {
                logger.warn("Unexpected exception from an event executor: ", t);
            }
        }
    });
}

该方法大致完成2件事:

  • thread = Thread.currentThread();:将executor线程池分配的线程保存起来,这样就完成了NioEventLoopThread线程的关联;

  • SingleThreadEventExecutor.this.run():具体实现在NioEventLoop.run()方法,所以,startThread()核心就是分配一个线程运行NioEventLoop.run()方法。

protected void run() {
    for (;;) {
        try {
            try {
                switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {
                case SelectStrategy.CONTINUE:// 默认实现下,不存在这个情况
                    continue;

                case SelectStrategy.BUSY_WAIT:

                case SelectStrategy.SELECT:
                    //selector.select轮询io事件
                    select(wakenUp.getAndSet(false));
                    if (wakenUp.get()) {
                        selector.wakeup();
                    }
                default:
                }
            } catch (IOException e) {
                rebuildSelector0();
                handleLoopException(e);
                continue;
            }

            cancelledKeys = 0;
            needsToSelectAgain = false;
            final int ioRatio = this.ioRatio;
            if (ioRatio == 100)&nb
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值