傻大方提要:【绝!真就一文全懂!Netty线程模型+启动详细分析+内存管理( 四 )】channel = channelFactory.newChannel(); 前面在ServerBootstrap实例设置服务端Channel时 , 设置了这个Channel的类型 , 这里就通过工厂类的方法生成NioServerSocketChannel对象...
按关键词阅读:
channel = channelFactory.newChannel();前面在ServerBootstrap实例设置服务端Channel时 , 设置了这个Channel的类型 , 这里就通过工厂类的方法生成NioServerSocketChannel对象 。
追溯NioServerSocketChannel的默认构造函数 , 我们可以发现在构造该实例时 , 设置了channel为非阻塞模式、SelectionKey.OP_ACCEPT事件、channelId 、NioMessageUnsafe(封装了用于数据传输操作的函数)、DefaultChannelPipeline和 NioServerSocketChannelConfig 属性 。
2.init这个Channel
void init(Channel channel) throws Exception {// 设置配置的option参数final Map我们发现init其实就做了三件事:
- 设置options、attrs
- 设置新接入Channel的options、attrs
- 将用于服务端注册的 Handler ServerBootstrapAcceptor 添加到 ServerChannel的ChannelPipeline 中 。 ServerBootstrapAcceptor 为一个接入器 , 专门接受新请求 。
ChannelFuture regFuture = config().group().register(channel);通过追溯我们发现过程如下: public ChannelFuture register(Channel channel) {return next().register(channel);}调用 next() 方法从 EventLoopGroup 中获取下一个 EventLoop , 调用 register() 方法注册: public ChannelFuture register(Channel channel) {return register(new DefaultChannelPromise(channel, this));}将Channel和EventLoop封装成一个DefaultChannelPromise对象 , 然后调用register()方法 。 DefaultChannelPromis为ChannelPromise的默认实现 , 而ChannelPromisee继承Future , 具备异步执行结构 , 绑定Channel , 所以又具备了监听的能力 , 故而ChannelPromis是Netty异步执行的核心接口 。 public ChannelFuture register(ChannelPromise promise) {ObjectUtil.checkNotNull(promise, "promise");promise.channel().unsafe().register(this, promise);return promise;}unsafe就是我们之前构造NioServerSocketChannel时new的对象 , 这里调用register方法过程如下:public final void register(EventLoop eventLoop, final ChannelPromise promise) {if (eventLoop == null) {throw new NullPointerException("eventLoop");}if (isRegistered()) {promise.setFailure(new IllegalStateException("registered to an event loop already"));return;}if (!isCompatible(eventLoop)) {promise.setFailure(new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));return;}AbstractChannel.this.eventLoop = eventLoop;// 必须要保证注册是由该EventLoop发起的if (eventLoop.inEventLoop()) {register0(promise);// 注册} else {// 如果不是单独封装成一个task异步执行try {eventLoop.execute(new Runnable() {@Overridepublic void run() {register0(promise);}});} catch (Throwable t) {logger.warn("Force-closing a channel whose registration task was not accepted by an event loop: {}",AbstractChannel.this, t);closeForcibly();closeFuture.setClosed();safeSetFailure(promise, t);}}} 首先通过isRegistered() 判断该 Channel 是否已经注册到 EventLoop 中;通过 eventLoop.inEventLoop() 来判断当前线程是否为该 EventLoop 自身发起的 , 如果是 , 则调用 register0() 直接注册;
如果不是 , 说明该 EventLoop 中的线程此时没有执行权 , 则需要新建一个线程 , 单独封装一个 Task , 而该 Task 的主要任务则是执行register0() 。
稿源:(未知)
【傻大方】网址:http://www.shadafang.com/c/111J293N2020.html
标题:绝!真就一文全懂!Netty线程模型+启动详细分析+内存管理( 四 )