Netty inEventLoop方法?异步回调?

文章目录


inEventLoop

一直对这个方法不是很理解,众所周知是判断当前线程是不是在当前的EventLoop中对应的那个线程?
一个channel对应一个且只对应一个EventLoop,一个Channel对应一个且只对应一个Pipeline,Pipline中包含handler(也是context),当前的Handler被Channel调用,那什么时候执行这段代码的线程不是channel对应的那个EventLoop中的线程?

EventExecutor中最关键的是inEventLoop方法,用于判断一个线程是否是EventExecutor内部那个线程,EventExecutor和EventLoop都是单线程实现。inEventLoop的主要使用场景是,当IO变化时,通过channel关联的pipeline会触发对应的事件,这些事件对应的执行pipeline中的处理链中handler的回调方法,每个handler添加到pipeline都可以指定自己的EventLoop,如果没指定,默认使用要添加的pipeline关联的channel注册到的EventLoopGroup中的某个EventLoop。所以channel通过pipeline调用handler时,如果handler没有单独指定EventLoop,那inEventLoop就会返回true,他俩由同一个线程处理,直接调用handler。如果handler单独指定了EventLoop,inEventLoop就会返回false,channel调用handler时就把要调用的方法封装到Runnable里,然后添加到handler指定的EventLoop的任务队列里,稍后会由对应的EventLoop中的线程执行。

来自:https://www.jianshu.com/p/d39ff4c98c5f

至于代码分析就不贴代码了,没有什么特别的,关键是情况的分析。

自己画了个图方便理解,当然肯定还有不对的地方,理解的不是很好,有问题希望提出共同进步!
在这里插入图片描述
所以会有下面两种情况
在这里插入图片描述

在handler中:
executor.inEventLoop()?
当前executor是channel对应的那个eventLoop,而inEventLoop中的currentThread是handler自定义的eventLoop,是不相等的。所以是false,false的时候将handler中的回调封装成task放到自己对应的eventLoop的任务队列中

这就是异步

当前的channel相当于是主线程,主线程想要回调,发现当前的handler有自己的处理线程,那么就把回调方法封装成task给他自己的Executor中的queue中,他自己去执行吧,我该干嘛干嘛去了。

拾遗


什么是异步?
是否要等待一个操作的完成?

什么是阻塞?
是否要等待一个数据准备好?


当然在Netty中还有一个比较有意思的:

WriteAndFlush和addListener方法,如果是异步的,在writeAndFlush之前,完成了AddListener,那么在WriteAndFlush执行完write有异常回调,或者,执行完flush回调operationComplete的时候,设置为了Success,是可以放心回调的。
可是如果是两个方法如果是同步执行,当然异步执行也可能,writeAndFlush执行完了,result设置为了Success,但是AddListener还没有添加,那要怎么回调?operationComplete还没有准备好呢。通过看源码能够知道notifyListenersNow的时候,先判断listeners(其实就是listener)是不是没有,没有直接return了,那不就意味着这次wirteAnfFlush事件没有回调了? 其实在AddListener方法中,会进行一次判断,判断当前的result是不是Success,是的话就会进行一次回调。
代码分析略。


还有ByteBuf的缓存和命中也应该细细体会。


声明:
笔者本身还是一个小白,只看到了冰山一角,不一定完全正确,如果文中存在严重的错误,希望尽快指出,不仅利于自己的修正,同时也减少他人产生对于知识的误解。

发布了554 篇原创文章 · 获赞 3996 · 访问量 283万+

猜你喜欢

转载自blog.csdn.net/dataiyangu/article/details/105357431