netty手动关闭资源的探究

最近突然得知自己的基础差,与精英的标准相距甚远。的确,平时的工作中,有太多机会允许我运用“基础”以外的东西去完成。让我对“基础”没有很重视,所以决定了马上亡羊补牢。就先从自己最看重的异步编程开刀吧,翻阅起了《Netty权威指南》。大部分内容与看之前的道听途说、自行猜想没差多少。突如其来的如下代码,让我产生了警觉:


1.png

代码中,由于手动打开了本地文件,所以在flush操作后,手动关闭了文件。但netty作为一个异步框架,总觉得不太可能需要写出这种同步样式的代码。
我的疑问有两点:1、flush方法返回时,可以确保数据write完毕?2、netty没有提供用于编写收尾逻辑的回调接口?
弄清疑问一:
尝试在互联网上搜索,发现并没有关于这点的描述,所以干脆自己下载了源码自己看。
ChannelHandlerContext接口,对flush的描述:

2.png

AbstractChannelHandlerContext抽象类中的具体实现:

3.png

意思应该是将pipeline中的ChannelOutboundHandler依次调一遍,参照findContextOutbound的实现:

4.png

可以得知,ChannelOutboundHandler是从后向前依次调用的。最后一个调用的为默认的HeadContext:

5.png

HeadContext的flush,调用的是DefaultChannelPipeline.channel().unsafe().flush():

6.png

7.png

以书中的示例代码使用的NioServerSocketChannel为例,当接收到客户端请求时,创建了NioSocketChannel:

8.png

8+.png

NioSocketChannel中unsafe().flush()的调用链为:
unsafe()[继承自:AbstractNioByteChannel、AbstractNioChannel] >>> AbstractChannel.unsafe()
AbstractChannel.unsafe()返回的结果来自:
NioSocketChannel.newUnsafe()

9.png

NioSocketChannelUnsafe的flush方法[继承自:NioByteUnsafe、AbstractNioUnsafe、AbstractUnsafe]:

10.png

调用的flush0方法:
flush0()[继承自:NioByteUnsafe、AbstractNioUnsafe] >>> AbstractUnsafe.flush0()

11.png

调用的NioSocketChannel.doWrite方法:

12.png

针对示例中的FileRegion,调用了父类doWrite方法:

13.png

14.png

其中确实存在针对write未完毕的处理,调用用incompleteWrite(true) >>> setOpWrite():

15.png

将SelectionKey.OP_WRITE注册到selector中,并在写操作完成后,由selector再触发一次flush(NioEventLoop代码):

16.png

总上,flush方法返回时,不保证数据write完毕。
弄清疑问二:
DefaultFileRegion的API说明:
Default FileRegion implementation which transfer data from a FileChannel or File. Be aware that the FileChannel will be automatically closed once AbstractReferenceCounted.refCnt() returns 0.
DefaultFileRegion类实现了FileRegion接口,继承了AbstractReferenceCounted类。创建DefaultFileRegion实例时可以传入一个FileChannel实现或一个File实例,而且在这里使用FileChannel不需要手动close。
上文的AbstractNioByteChannel.doWrite方法中,完毕时调用了ChannelOutboundBuffer.remove():

17.png

这正是用来释放ReferenceCounted对象的逻辑。
DefaultFileRegion中也存在关闭FileChannel的逻辑:

18.png

但RandomAccessFile方法中,不只有关闭FileChannel的逻辑:

19.png

因此RandomAccessFile.close()方法还是需要手动调用的。
总终方案:
编写DefaultFileRegion子类,重写deallocate方法,额外关闭RandomAccessFile对象。(代码略)

探究感想:
为了论证自己的猜测,确实花费了不少精力。最大的困难在于本次的论点,没有被广大程序员关注,而且错误的代码遍布各种书籍、网站,让人直觉上认为那些就是对的。这正让我联想到之前美团的招聘细则中不要“信中医的”。中医这里代表的是广泛留传下来的传统中医理论知识,不单只运用了现代科学医药手段验证过的中医。中医与软件理论,都十分庞大、且充满糟粕。对待中医和软件知识,都应该持有一种警觉态度,那些被记载、流传下来的手段、方案,真的是正确的吗?适用在你的场景中依然有效?的确,实际运用中会有众多因素,制约着你无法透彻的去验证。但你的知识获取方法,只能是听信他人吗。1753年英国海军军医伦达,经试验得出结论:柠檬汁可用来治疗和预防坏血病。这种的结论,对于航海而言就足够了,不需要知道其根本是维生素C的作用。中医知识通过大量随机双盲对照试验来验证。软件知识,归根到底就是代码,真有什么不明白的,看一看、运行一下。你能了解到什么程度,首先由你想了解到什么程度决定。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容