Netty之 Recycler 对象回收池的内部结构

757 阅读4分钟

「我正在参与掘金会员专属活动-源码共读第一期,点击参与

前言

在上篇文章, 我们一起简单的学习了Recycler的定义概念和简单实现, 本篇内容我们对其进行源码分析

上篇文章: Netty之了解 Recycler 对象回收池 - 掘金 (juejin.cn)

本篇文章添加于我的Netty专栏 欢迎大家关注

本篇文章的主要内容是带领大家简单学习和了解NettyRecycler, 并完成本次源码活动的任务二

image.png

源码分析开始

继承实现类

老规矩, 先从查看继承实现类开始, 但是你点开Recycler类的继承实现图之后你就会发现, 压根毛都没有啊

image.png

好吧, 实际上在之前就应该能发现的, 毕竟这个类上确实也没有继承和实现其他的类, 这波可以嘲讽一手

image.png

销毁方法分析

OK, 没有继承实现类, 那么方法肯定很多的吧, 毕竟这个类还是很重要的, 在IDEAAlt+7查看方法

好家伙, 我们直接看他自己的实现, 对外开放的方法(public) 一共就俩, get()recycle(T o, Handle<T> handle), 这还分析个锤子, 这不就是获取对象的方法和销毁方法吗, 销毁方法还弃用凉凉了, 本章结束

image.png

好吧, 就这么结束的话, 估计掘金首推是没了, 继续凑凑字数

既然Recycler的销毁方法没有了, 那真正的销毁方法在哪里呢, 我们去看一下

这里可能是提交代码的注释, 我也不知道, 没研究过, 但是每次都会给我惊喜, 可以看到, 他说这个方法被注释掉了, 如果你想调用销毁方法, 那么你就去调用handle的销毁方法recycler

image.png

我们继续看他这个注释, Recycler.Handle.recycle(Object)这个方法有没有一种熟悉的感觉, 在我们最开始无中生有的找继承实现图的时候就有看到过, 是不是, 我们就去看一看

好像被耍了一样, 这里确实有一个Handler, 也确实有recycle方法, 但是里面是空的啊, 这怎么搞

image.png

稳住不慌, 如果你看过我上篇文章的话, 还记不记得我们创建的对象池也重写了这个方法

上篇文章地址: Netty之了解 Recycler 对象回收池 - 掘金 (juejin.cn)

image.png

跟着往下走可以看到这个销毁方法确实存在, 还是存在于Recycler这个类中, 第一个就不看了, 我也看不懂. 直接进入到class类中了, 有明白的大佬可以评论区告诉我一下, 感谢

image.png

进入实际的recycle()方法之后可以看到他调用了localPool.release(this);这个方法调用也能猜出来, 肯定就是本地线程池的销毁方法嘛, 继续往下走

image.png

这个方法我们直接Ctrl+f搜索, 你要问我为什么, 那肯定是因为LocalPool是一个内部类啊...

其他我们暂时不管, 还是往下看, handlers,relaxedOffer, 可以看到handlers是一个队列Queue, 那么offer相关的肯定就是进入队列了, 继续往下走, 老规矩, 搜索这个方法

image.png

到最后, 其实我们还在这一个方法里面没有出去, 可以看到, 最后就是一个单纯地进入队列操作了

image.png

image.png

销毁到这里我们也就结束了

获取对象方法

获取对象方法就不逐行分析了, 简单将将就行:

  • 判断线程池的容量, 如果为0 则直接调用抽象方法newObject()
  • 获取回收池对象
  • 判断当前的handle对象是否为null
  • 如果为 null, 则创建对象
  • 不为 null, 则直接取出来返回

image.png

总结

构造图我记得IDEA可以生成, 但是我真的是没有找到...

我就简单介绍一下Recycler这个类吧

  • 主要有两个方法
    • get()获取回收队列中的第一个对象, 若没有则创建一个对象
    • recycler()销毁对象, 将其放入回收队列中
  • newObject()抽象方法, 创建新对象的方法
  • DefaultHandle内部类, 对象的包装类
  • LocalPool内部类, 回收队列池, 保存实际回收对象
  • BlockingMessageQueue内部类, 线程安全相关的

image.png




本文内容到此结束了

如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。

如有错误❌疑问💬欢迎各位大佬指出。

我是 宁轩 , 我们下次再见