一。接上一篇
https://blog.51cto.com/483181/2121265
我们继续分析doBind0 (regFuture、通道、localAddress承诺)
<代码>私人ChannelFuture doBind(最终SocketAddress localAddress都){ 最后ChannelFuture regFuture=initAndRegister (); 最终频道频道=regFuture.channel (); 如果(regFuture.cause () !=null) { 返回regFuture; } 如果(regFuture.isDone ()) {//在这一点上我们知道登记是完整的和成功的。 ChannelPromise承诺=channel.newPromise (); doBind0 (regFuture、通道、localAddress承诺);//3。我们这篇要分析的内容 返回的诺言; 其他}{ … 返回的诺言; } }代码>
二。doBind0
2.1 - 4个参数
如上面代码,doBind0有4个参数regFuture,通道,localAddress,承诺,它们的类型如下:
regFuture: DefaultChannelPromise
频道:NioServerSocketChannel
localAddress: SocketAddress
都承诺:DefaultChannelPromise
那继续往下面看代码,
<代码>私有静态孔隙doBind0 ( 最后ChannelFuture regFuture,最终频道频道, 最终SocketAddress localAddress都最终ChannelPromise承诺){//这个方法被调用之前channelRegistered()被触发。给用户处理程序设置的机会//管道的channelRegistered()实现。 channel.eventLoop ()。执行(新Runnable () { @Override 公共空间run () { 如果(regFuture.isSuccess ()) { 通道。bind (localAddress承诺).addListener (ChannelFutureListener.CLOSE_ON_FAILURE); 其他}{ promise.setFailure (regFuture.cause ()); } } }); }代码>
doBind0()代码很简单、调用channel.eventloop()执行了一个Runnable.channel.eventloop()调用的是AbstractChannle.eventloop ()
<代码> @Override 公共EventLoop EventLoop () { EventLoop EventLoop=this.eventLoop; 如果(eventLoop==null) { 把新的IllegalStateException(“通道不注册一个事件循环”); } 返回eventLoop; }代码>
而this.eventLoop初始化是在注册的时候,具体可以参考上一篇结合初始化的分析
https://blog.51cto.com/483181/2121265
<代码> @Override 公共最终无效注册(EventLoop EventLoop,最终ChannelPromise承诺){ … AbstractChannel.this。eventLoop=eventLoop; … }代码>
它的类型是一个NioEventLoop,所以它就是往自己的线程池里面丢了一个可运行的任务
NioEventLoop的继承关系图如下:
我们可以看一下NioEventLoop。执行(Runnable)方法。
2.2执行(Runnable)方法
这个方法的实现是在SingleThreadEventExecutor.java里面。
<代码>私人最终QueuetaskQueue; @Override 公共空间执行(Runnable任务){ 如果(任务==null) { 把新NullPointerException(“任务”); } 布尔inEventLoop=inEventLoop (); addTask(任务); 如果(! inEventLoop) { startThread (); 如果(isShutdown (),,removeTask(任务)){ 拒绝(); } } 如果(!addTaskWakesUp,,wakesUpForTask(任务)){ 唤醒(inEventLoop); } } 保护无效addTask (Runnable任务){ 如果(任务==null) { 把新NullPointerException(“任务”); } 如果(! offerTask(任务)){ 拒绝(任务); } } 最后布尔offerTask (Runnable任务){ 如果(isShutdown ()) { 拒绝(); } 返回taskQueue.offer(任务); }代码>
它是把传入的Runnable对象放到一个taskQueue队列里面。
那我们继续看Runnable里面的实现,channel.bind (xxxx)
<代码> channel.eventLoop ()。执行(新Runnable () { @Override 公共空间run () { … 通道。bind (localAddress承诺).addListener (ChannelFutureListener.CLOSE_ON_FAILURE); } });代码>
2.3 channel.bind
频道的类型是NioServerSocketChannel,而绑定方法的实现类是在AbstractChannel.java里面。
<代码> @Override 公共ChannelFuture绑定(SocketAddress localAddress都,ChannelPromise承诺){ 返回管道。bind (localAddress、承诺); }代码>
调用的是pipeline.bind (xxx),管道我们知道,它链接了ChannelHandler的背景下,有头和tail.head是出站,尾巴是入站。