写点什么

Netty inEventLoop 方法?异步回调?Promise,mongodb 面试题目

作者:MySQL神话
  • 2021 年 11 月 27 日
  • 本文字数:1886 字

    阅读完需:约 6 分钟

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


为什么返回 Promise


==========================================================================


阿西,实在不想贴代码


平常用户代码习惯这么写:


public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {


ChannelFuture future = ctx.writeAndFlush("test data");


future.addListener(new ChannelFutureListener() {


@Override


public void operationComplete(ChannelFuture future) throws Exception {


if (future.isSuccess()){


System.out.println("写出成功");


}else{


System.out.println("写出失败");


}


}


});


}


为什么 writeAndFlush 返回 future,下面通过 future 调用 addListener?


在 writeAndFlush 方法中返回了 promise,也就是 future



在 addListener 方法中有一个 isDone 方法



然后 isDone0



判断 result 状态,这个 result 状态就是 DefaultPromise 中的,在 writeAndFlush 中 flush 也能修改这个状态,所以是在 writeAndFlush 和 addListener 中相同的。


Promise 继承自 Future,Future 中有 isSuccess 方法



所以在 operationComplete 方法中能够执行 future.isSuccess(),即这个promise(也就是futrure)是writeAndFlush和addListener的一个桥梁,分享着当前是否能够回调的状态(是不是写完了)


这理解其实和 JDK JUC 中的 Future 是一个意思了:


promise(也就是 futrure)中的 result 也是一个状态值,如果 writeAndFlush 完成了,设置值 success,并且去主动唤醒,或者在 addListener 中主动唤醒。


区别就是 Future 中是通过 get 方法被动唤醒的,所以时机可能不是那么的准确。


另外 jdk 中的 futrue 方法是通过 get 阻塞进行的,runnable 通过 run 生产数据,Future 通过 get 获取数据,FuturetTask 被两者共享,继承自他们两个,拥有了 run 和 get 这两个功能,在自导自演,run 中执行 callable 的 call 方法,执行完成设置可执行标志,没有完成则标志还是未完成的,get 方法一直阻塞,可是如果已经生产好了,而没有 get 呢?所以在 Netty 中通过 listener 这种方法更加精准的添加了监听,能够第一时间回调。


![在这里插入图片描述](https://img-blog.csdnimg.cn/20200407111138235.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RhdGFpeWFuZ3U=,size_16,color_FFFFF


《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享


F,t_70)


拾遗


================================================================




什么是异步?


是否要等待一个操作的完成?


什么是阻塞?


是否要等待一个数据准备好?




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


WriteAndFlush 和 addListener 方法,如果是异步的,在 writeAndFlush 之前,完成了 AddListener,那么在 WriteAndFlush 执行完 write 有异常回调,或者,执行完 flush 回调 operationComplete 的时候,设置为了 Success,是可以放心回调的。


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


代码分析略。




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




声明:


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

总结

虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。




上面提到的关于这些 JAVA 基础、三大框架、项目经验、并发编程、JVM 及调优、网络、设计模式、spring+mybatis 源码解读、Mysql 调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料


有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。


本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

用户头像

MySQL神话

关注

还未添加个人签名 2021.11.12 加入

还未添加个人简介

评论

发布
暂无评论
Netty  inEventLoop方法?异步回调?Promise,mongodb面试题目