Netty Recycler源码解读

作者: 良辰美景TT | 来源:发表于2018-12-12 11:23 被阅读0次

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

    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里,逻辑如下图:

    相关文章

      网友评论

        本文标题:Netty Recycler源码解读

        本文链接:https://www.haomeiwen.com/subject/awhehqtx.html