Netty之了解 Recycler 对象回收池

700 阅读3分钟

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

前言

RecyclerNetty中的对象回收池, 用于复用对象, 减少内存分配和GC操作的次数, 它通过双向链表维护对象池, 在对象被回收的时候将其插入到链表的头部, 在对象需要被分配时从链表的头部取出, 这样可以减少内存分配的次数, 提高系统的效率, 接下来让我们学习一下Recycler 的复用对象

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

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

image.png

自定义 User 类的对象复用

首先我们创建一个User类, 定义一个属性Recycler.Handle<User> handle, 并重写销毁方法recycler()和构造方法

public class User {
    private String name;
    private Recycler.Handle<User> handle;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public User(Recycler.Handle<User> handle) {
        this.handle = handle;
    }
    public void recycle() {
        handle.recycle(this);
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", handle=" + handle +
                '}';
    }
}

然后去创建User类的对象回收池UserRecycler类, 让这个类去继承Recycler对象回收类, 并重写抽象方法newObject(Handle handle)

public class UserRecycler extends Recycler<User>{
    @Override
    protected User newObject(Handle handle) {
        return new User(handle);
    }
}

最后我们创建一个Test测试类, 写一个mian方法来对我们自定义的对象回收池来进行测试

public class Test {
    public static void main(String[] args) {
        // 创建对象回收池对象
        Recycler<User> userRecycler = new UserRecycler();
        // 从对象回收池中获取对象
        User user1 = userRecycler.get();
        // 赋予对象属性值
        user1.setName("宁轩");
        // 回收 user1
        user1.recycle();
        // 重新从对象回收池中获取对象
        User user3 = userRecycler.get();
        // 判断两个对象是否相等
        System.out.println(user1 == user3);
        // 输出新获取对象的 name 属性
        System.out.println(user3);
    }
}

我们测试的流程大概如下:

  • 先通过对象池获取 对象A
  • 给 对象A 赋予值
  • 销毁 对象A
  • 再次从对象池中获取 对象B
  • 判断 对象A 是否等于 对象B
  • 输出 对象B 的 name 属性

下图是我们的测试结果, 可以看到, 我们新创建的对象user3 和之前创建的对象user1 是完全相等的

面试小知识: == 判断的是引用地址, equals 判断的是值, 需要重写 equals()方法

image.png

那么有没有可能每一次创建的对象都是一个? 接下来我们继续测试

本次测试, 其他不变, 继续从对象池中获取新的对象 user4, 然后和 user1 进行判断, 可以看到, 他俩完全不一样, user4 是一个纯纯的新对象

image.png

本次测试, 将 user1 销毁的步骤注释掉, 可以看到, 这个时候 user1 != user3, 这两个对象也不一样了

image.png

由此可得知, 当一个对象销毁之后, 再次从对象池中获取到的就是该对象, 若对象池中没有已销毁的对象, 那么获取到的就是新对象, 此时我们在回顾一下前言的内容, 是不是更加理解了呢

image.png

总结

本篇文章就到这里了, 通过本篇文章的学习, 我们能够理解了NettyRecycler究竟是什么, 有什么作用, 但是他的内部结构和各种方法我们都没有去详细的研究, 这就交给下一篇文章了, 最后我们一起简单的实现了一下对象池希望对大家理解Recycler有所帮助




本文内容到此结束了

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

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

我是 宁轩 , 我们下次再见