Netty中的各个关键时间点(一)

前置说明

本文主要记录Netty中的一些主要的关键时间点,是理解Netty 和 事件驱动的关键。也是阅读Netty源码的指导。

代码来源:Netty 4.1.77

本文涉及到的角色:

角色:主线程,主Reactor线程(bossGroup中的EventLoop), 从Reactor线程(workGroup中的EventLoop),结合Reactor编码模型理解

PS:Netty中的主要事件节点不断完善中,看看后面要不要拆成多篇。。。

主Reactor线程的启动时间点

主线程调用ServerBootStrap.bind方法,会通过io.netty.bootstrap.AbstractBootstrap#initAndRegister方法,先初始化NioServerSocktChannel,然后把NioServerSocktChannel注册到主Reactor线程组中的一个主Reactor线程上

    final ChannelFuture initAndRegister() {
        Channel channel = null;
        try {
            // 创建和初始化
            channel = channelFactory.newChannel();
            init(channel);
        } catch (Throwable t) {
            if (channel != null) {
                // channel can be null if newChannel crashed (eg SocketException("too many open files"))
                channel.unsafe().closeForcibly();
            }
            // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
            return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
        }
        //注册
        ChannelFuture regFuture = config().group().register(channel);
        if (regFuture.cause() != null) {
            if (channel.isRegistered()) {
                channel.close();
            } else {
                channel.unsafe().closeForcibly();
            }
        }

        return regFuture;
    }

最终会调用该主Reactor线程的注册方法进行注册:io.netty.channel.AbstractChannel.AbstractUnsafe#register,

        @Override
        public final void register(EventLoop eventLoop, final ChannelPromise promise) {
            ...
            //检查相关代码忽略

            AbstractChannel.this.eventLoop = eventLoop;

            if (eventLoop.inEventLoop()) {
                register0(promise);
            } else {
                try {
                    //当前是Main线程调用,所以提交任务到ServerChannel对应的Reactor线程
                    eventLoop.execute(new Runnable() {
                        @Override
                        public void run() {
                            register0(promise);
                        }
                    });
                } catch (Throwable t) {
                    异常处理忽略。。。
                }
            }
        }

由于是主线程调用的该方法,所以会通过io.netty.util.concurrent.SingleThreadEventExecutor#execute(java.lang.Runnable) -> io.netty.util.concurrent.SingleThreadEventExecutor#execute(java.lang.Runnable, boolean) 提交一个异步任务到该主Reactor线程,

private void execute(Runnable task, boolean immediate) {
        boolean inEventLoop = inEventLoop();
        addTask(task); //把注册任务提交到主Reactor线程的任务队列
        if (!inEventLoop) {//当前是Main线程,需要启动主Reactor线程
            startThread();
            if (isShutdown()) {
                boolean reject = false;
                try {
                    if (removeTask(task)) {
                        reject = true;
                    }
                } catch (UnsupportedOperationException e) {

                }
                if (reject) {
                    reject();
                }
            }
        }

        if (!addTaskWakesUp && immediate) {
            wakeup(inEventLoop);
        }
    }

然后主线程调用io.netty.util.co

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值