前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty Recycler源码解读

Netty Recycler源码解读

作者头像
良辰美景TT
发布2018-12-26 16:13:02
1.1K0
发布2018-12-26 16:13:02
举报
文章被收录于专栏:java、Spring、技术分享

Recycler是一个轻量级的对象缓存池,用来实现对象的复用。下面是使用Recycler的一个简单实例:

代码语言:javascript
复制
import io.netty.util.Recycler;

public class RecycleTest {
    private static final Recycler<User> RECYCLER = new Recycler<User>() {
        //没有对象的时候,新建一个对象, 会传入一个handler,在Recycler池里,所有的对象都会转成DefaultHandle对象
        @Override
        protected User newObject(Handle<User> handle) {
            return new User(handle);
        }
    };

    private static class User {
        private final Recycler.Handle<User> handle;

        public User(Recycler.Handle<User> handle) {
            this.handle = handle;
        }

        public void recycle() {
            //通过handler进行对象的回收
            handle.recycle(this);
        }
    }

    public static void main(String[] args) {
        User user = RECYCLER.get();
        //直接调用user方法进行对象的回收
        user.recycle();

        User user1 = RECYCLER.get();
        //这里会返回true
        System.out.println(user1 == user);
    }
}
Recycler对象的创建

Recycler内部通过FastThreadLocal里的Stack栈来保存对象池,每次通过get方法从池中得到对象的时候,先通过FastThreadLocal得到Stack对象,具体的参数含义如下图所示:

Stack里通过数组存储着回收的对象,构造方法如下图:

Stack的构造方法

对象的回收

Recycler对象的回收会调用stack的push方法将对象放入到栈里,这样就完成了对象的回收,具体逻辑如下:

在push方法里,根据线程的不同,又可以分为同线程的回收,与异线程的回收。

同线程对象的回收

线程的回收相对比较简单,将对象放到Stack栈里就完成了对象的回收,代码如下:

判断对象是否回收的逻辑:

异线程对象的回收

异线程的回收是指创建对象的线程与调用recycler方法的线程不是同一个线程,这时候的回收逻辑就相对复杂了,里面用到了两个对象,分别为:

  • WeakOrderQueue 存储其它线程回收到本线程的对象,当某个线程从Stack中获取不到对象时会从WeakOrderQueue中获取对象。每个线程的Stack拥有1个WeakOrderQueue链表,链表每个节点对应1个其它线程的WeakOrderQueue,其它线程回收到该Stack的对象就存储在这个WeakOrderQueue里。
  • Link: WeakOrderQueue中包含1个Link链表,回收对象存储在链表某个Link节点里,当Link节点存储的回收对象满了时会新建1个Link放在Link链表尾,Link的容量为16。 对象结构如下图所示:

具体的回收过程可以分为:

  • 获取WeakOrderQueue
  • 如果没有相应的WeakOrderQueeu,则会创建WeakOrderQueue, 将创建线程的Stack与回收线程的WeakOrderQueue进行绑定,具体的代码如下:
  • 将对象追加到WeakOrderQueue
  • WeakOrderQueue的构造方法如下:
  • Link构造方法
获取一个对象

可以通过get方法从recycler对象里获取一个缓存的对象,下面是get方法的逻辑:

Recycler的get方法逻辑

Stack的pop方法

从其它线程获取对象放到stack里
  • 从其它线程获取对象入口
  • 从其它线程攻取对象
  • 将Link集合里的对象移到stack里,逻辑如下图:
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.12.12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Recycler对象的创建
  • 对象的回收
    • 同线程对象的回收
      • 异线程对象的回收
      • 获取一个对象
        • 从其它线程获取对象放到stack里
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档