我们进入到Recycler的构造函数:
protected Recycler() {
this(DEFAULT_MAX_CAPACITY_PER_THREAD);
}
然后在这个类里面,有一个threadLocal,里面放了一个stack:
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就是放我们的handle的。
看看stack的成员变量:
// we keep a queue of per-thread queues, which is appended to once only, each time a new thread other
// than the stack owner recycles: when we run out of items in our stack we iterate this collection
// to scavenge those that can be reused. this permits us to incur minimal thread synchronisation whilst
// still recycling all items.
final Recycler<T> parent;
final Thread thread;
final AtomicInteger availableSharedCapacity;
final int maxDelayedQueues;
private final int maxCapacity;
private final int ratioMask;
private DefaultHandle<?>[] elements;
private int size;
private int handleRecycleCount = -1; // Start with -1 so the first one will be recycled.
private WeakOrderQueue cursor, prev;
private volatile WeakOrderQueue head;
parent:不用说就是当前的Recycler
thread:当前的thread
maxDelayedQueues:我们的对象可能在一个线程里面创建(get),另外一个线程那里释放,这个对象就不会放在第一个线程的数组里,而是放在另外一个线程的WeakOrderQueue里面。那么一个线程创建的对象可以在多少个不同的线程里面缓存呢?就是这个值了
找默认值:
MAX_DELAYED_QUEUES_PER_THREAD = max(0,
SystemPropertyUtil.getInt("io.netty.recycler.maxDelayedQueuesPerThread",
// We use the same value as default EventLoop number
Runtime.getRuntime().availableProcessors() * 2));
也就是我们处理器的个数的两倍。
maxCapacity:这个stack的最大容量,也就是池的大小,也就是一个线程里面最多可以放多少个对象。
找来找去我们可以看到他的默认值是:
private static final int DEFAULT_INITIAL_MAX_CAPACITY_PER_THREAD = 32768; // Use 32k instances as default.
也就是我们一个数组里面可以放32k个对象。
availableSharedCapacity:上面讲了可以在不同的线程释放缓存对象,这个参数就是一个线程里面可以缓存别的线程对象的最大的个数。
默认值是:
availableSharedCapacity = new AtomicInteger(max(maxCapacity / maxSharedCapacityFactor, LINK_CAPACITY));
而这个maxSharedCapacityFactor的默认值可以找到:
MAX_SHARED_CAPACITY_FACTOR = max(2,
SystemPropertyUtil.getInt("io.netty.recycler.maxSharedCapacityFactor",
2));
是2。
LINK_CAPACITY默认值是16:
LINK_CAPACITY = safeFindNextPositivePowerOfTwo(
max(SystemPropertyUtil.getInt("io.netty.recycler.linkCapacity", 16), 16));
结合前面我们要分析的maxCapacity默认值为32k,我们可以知道这个availableSharedCapacity是32k/2=16k。
也就是说线程里面可以拥有自己的对象是32k个,外部线程的对象是16k个。
ratioMask:每次通过调用recycle把对象进行回收的时候,它并不是每次都会把对象进行回收的,这个参数用来控制对象回收的频率。
先看这个RATIO的默认值:
/ By default we allow one push to a Recycler for each 8th try on handles that were never recycled before.
// This should help to slowly increase the capacity of the recycler while not be too sensitive to allocation
// bursts.
RATIO = safeFindNextPositivePowerOfTwo(SystemPropertyUtil.getInt("io.netty.recycler.ratio", 8));
然后:
protected Recycler(int maxCapacityPerThread, int maxSharedCapacityFactor,
int ratio, int maxDelayedQueuesPerThread) {
ratioMask = safeFindNextPositivePowerOfTwo(ratio) - 1;
if (maxCapacityPerThread <= 0) {
this.maxCapacityPerThread = 0;
this.maxSharedCapacityFactor = 1;
this.maxDelayedQueuesPerThread = 0;
} else {
this.maxCapacityPerThread = maxCapacityPerThread;
this.maxSharedCapacityFactor = max(1, maxSharedCapacityFactor);
this.maxDelayedQueuesPerThread = max(0, maxDelayedQueuesPerThread);
}
}
所以这个是7
elements:这个就是这个stack里面的元素了,都是DefaultHandler
cursor、prev、head:这个就是存放了其他线程的链表的指针,也就是WeakOrderQueue的指针,后续我们好好分析。