netty源码阅读之性能优化工具类之Recycler获取对象

38 篇文章 1 订阅
33 篇文章 1 订阅

 Recycler获取对象主要分为以下几部分:

1、获取当前线程的Stack

2、从Stack里面弹出对象

3、如果弹出对象为空,那就创建对象并且绑定到Stack里面

我们从Recycler的get方法进入,就是这个源码:

    @SuppressWarnings("unchecked")
    public final T get() {
        if (maxCapacityPerThread == 0) {
            return newObject((Handle<T>) NOOP_HANDLE);
        }
        Stack<T> stack = threadLocal.get();
        DefaultHandle<T> handle = stack.pop();
        if (handle == null) {
            handle = stack.newHandle();
            handle.value = newObject(handle);
        }
        return (T) handle.value;
    }

首先看maxCapacityPerThread==0这个分支,看NOOP_HANDLE这个源码:

    @SuppressWarnings("rawtypes")
    private static final Handle NOOP_HANDLE = new Handle() {
        @Override
        public void recycle(Object object) {
            // NOOP
        }
    };

 recycle的时候,什么是都不做。

也就是,如果maxCapacityPerThread为0,我们就什么对象都不缓存。

一、获取当前线程的Stack

就是这段代码:

        Stack<T> stack = threadLocal.get();

获取当前线程的stack。 

threadLocal就是FastThreadLocal:

    private final FastThreadLocal<Stack<T>> threadLocal = new FastThreadLocal<Stack<T>>() {
        @Override
        protected Stack<T> initialValue() {
            return new Stack<T>(Recycler.this, Thread.currentThread(), maxCapacityPerThread, maxSharedCapacityFactor,
                    ratioMask, maxDelayedQueuesPerThread);
        }
    };

初始化的时候,会新建一个stack。 

二、从Stack里面弹出对象

这个对象就是pop对象。

DefaultHandle<T> handle = stack.pop();

pop出来的对象是一个handle,对象就存在handle里面,也就是要返回的就是handle.value。

然后我们分析pop的过程:

        @SuppressWarnings({ "unchecked", "rawtypes" })
        DefaultHandle<T> pop() {
            int size = this.size;
            if (size == 0) {
                if (!scavenge()) {
                    return null;
                }
                size = this.size;
            }
            size --;
            DefaultHandle ret = elements[size];
            elements[size] = null;
            if (ret.lastRecycledId != ret.recycleId) {
                throw new IllegalStateException("recycled multiple times");
            }
            ret.recycleId = 0;
            ret.lastRecycledId = 0;
            this.size = size;
            return ret;
        }

 首先有一个size,这个size就是这个stack里面有多少个对象。如果size等于0,就会调用scavenge(),意思就是如果当前线程没有对象了,但是我的对象有可能在别的线程那里有对象,就去别的线程那里找,后面再分析这个方法。

后续如果size不为0,那就从stack里面取,size--。

DefaultHandle ret = elements[size]; elements[size] = null;就是把对象取出来并且设置原来的对象为null。

然后:

            ret.recycleId = 0;
            ret.lastRecycledId = 0;

这两段代码的意思就是,对象被使用了,并没有在回收次里面。

 

三、创建对象并且绑定到Stack里面

这一段源代码就是我们这里要分析的内容:

        if (handle == null) {
            handle = stack.newHandle();
            handle.value = newObject(handle);
        }

handle为空,就在stack里面新建一个handle:


        DefaultHandle<T> newHandle() {
            return new DefaultHandle<T>(this);
        }

这个handle是DefaultHandle并且把this传入进去,这个this就是stack:


        DefaultHandle(Stack<?> stack) {
            this.stack = stack;
        }

也就是每个handle都绑定了一个stack。

最后handle.value=newObject(handle)就是我们要的对象,这里也不是很复杂。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值