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)就是我们要的对象,这里也不是很复杂。