前言
Recycler
是Netty
中的对象回收池, 用于复用对象, 减少内存分配和GC
操作的次数, 它通过双向链表维护对象池, 在对象被回收的时候将其插入到链表的头部, 在对象需要被分配时从链表的头部取出, 这样可以减少内存分配的次数, 提高系统的效率, 接下来让我们学习一下Recycler
的复用对象
自定义 User 类的对象复用
首先我们创建一个User
类, 定义一个属性Recycler.Handle<User> handle
, 并重写销毁方法recycler()
和构造方法
publicclassUser { privateStringname; privateRecycler.Handlehandle; publicvoidsetName(Stringname) { this.name=name; } publicStringgetName() { returnname; } publicUser(Recycler.Handlehandle) { this.handle=handle; } publicvoidrecycle() { handle.recycle(this); } publicStringtoString() { return"User{"+"name='"+name+'\''+", handle="+handle+'}'; } }
然后去创建`User`类的对象回收池`UserRecycler`类, 让这个类去继承`Recycler`对象回收类, 并重写抽象方法`newObject(Handle handle)`
publicclassUserRecyclerextendsRecycler{ protectedUsernewObject(Handlehandle) { returnnewUser(handle); } }
最后我们创建一个`Test`测试类, 写一个`mian`方法来对我们自定义的对象回收池来进行测试
publicclassTest { publicstaticvoidmain(String[] args) { // 创建对象回收池对象RecycleruserRecycler=newUserRecycler(); // 从对象回收池中获取对象Useruser1=userRecycler.get(); // 赋予对象属性值user1.setName("宁轩"); // 回收 user1user1.recycle(); // 重新从对象回收池中获取对象Useruser3=userRecycler.get(); // 判断两个对象是否相等System.out.println(user1==user3); // 输出新获取对象的 name 属性System.out.println(user3); } }
我们测试的流程大概如下:
- 先通过对象池获取 对象A
- 给 对象A 赋予值
- 销毁 对象A
- 再次从对象池中获取 对象B
- 判断 对象A 是否等于 对象B
- 输出 对象B 的 name 属性
下图是我们的测试结果, 可以看到, 我们新创建的对象user3 和之前创建的对象user1 是完全相等的
面试小知识: == 判断的是引用地址, equals 判断的是值, 需要重写 equals()方法
那么有没有可能每一次创建的对象都是一个? 接下来我们继续测试
本次测试, 其他不变, 继续从对象池中获取新的对象 user4, 然后和 user1 进行判断, 可以看到, 他俩完全不一样, user4 是一个纯纯的`新对象`
本次测试, 将 user1 销毁的步骤注释掉, 可以看到, 这个时候 `user1 != user3`, 这两个对象也不一样了
由此可得知, 当一个对象销毁之后, 再次从对象池中获取到的就是该对象, 若对象池中没有已销毁的对象, 那么获取到的就是新对象, 此时我们在回顾一下`前言`的内容, 是不是更加理解了呢
总结
本篇文章就到这里了, 通过本篇文章的学习, 我们能够理解了Netty
的Recycler
究竟是什么, 有什么作用, 但是他的内部结构和各种方法我们都没有去详细的研究, 这就交给下一篇文章了, 最后我们一起简单的实现了一下对象池
希望对大家理解Recycler
有所帮助