一、引言
在上一小节中,根据过往线程池的经验,在没有阅读Netty的Recycler对象池源码之前,根据对象池的基本功能,手写了一个简易版的对象池代码。
然而解决多线程并发使用的是ReentrantLock,所有线程的所有操作都要获取同一把锁,在高并发场景下,很难满足业务需求,等待锁的时间有可能比在内存中新建个对象的时间都要长;想要提升性能,还可以使用比如分段锁、有CAS功能的容器(CopyOnWriteArrayList)、每个线程都有属于自己的容器可直接避免这个问题(ThreadLocal)。
本文将根据Netty的Recycler的源码,面对上一小节中的对象池需求,Recycler是怎么实现的,以及为什么可以抗住高并发场景下的IO读写功能。
二、代码
-
有获取和回收两个功能
通过 acquire() 方法从池中获取对象,release() 方法将对象归还给池。
1.1 对象存储
对象池场景中,每次获取一个对象,所以可以使用类似栈或队列或者链表结构存储,而最近使用的对象更可能在 CPU 缓存中,所以栈结构更适合对象池,并且要求容器是基于CAS线程安全的,所以Netty自定义了一个高效、线程安全且适配对象复用场景的 “栈式存储结构”Stack,一个Stack对象就是一个对象池容器,其中elements是真正存放元素的数组对象。
static final class Stack<T> {
// 所属的Recycler
final MyNettyRecycler<T> parent;
// 所属线程
final Thread thread;
// 栈数组
private DefaultHandle<?>[] elements;
// 栈大小
private final int maxCapacity;
// 当前栈顶索引
private int size;
// 弱引用队列,用于在全局对象池中CAS获取对象
private volatile WeakOrderQueue cursor, prev, head;
}
1.2 传入某类对象的构造方法
在上一篇文章里,使用的是把构造方法和对象初始化方法作为一个参数传给对象池,但是那种方式只支持某种特定的格式,比如传入一个无参的构造方法,不是很灵活,而Netty则是把对象创建和初始化方法放在使用的地方。
private static final Recycler<MyObject> RECYCLER = new Recycler<MyObject>() {
@Override
protected MyObject newObject(Handle<MyObject> handle) {
// 定义对象创建逻辑,需绑定Handle以支持后续回收
return new MyObject(handle);
}
};
// 待复用的对象类
static class MyObject {
private final Recycler.Handle<MyObject> handle;
public MyObject(Recycler.Handle<MyObject> handle) {
this.handle = handle;
}
// 回收对象到池中的方法
public void recycle() {
// 在这里需要用户自己实现对象初始化,比如把id这个变量初始化成-1
handle.recycle(this);
}
}
Recycler是一个抽象类,里面有newObject需要使用者自定义,同时还定义了Handle类和DefaultHandle类,作为对象如何"清理状态" 和 "如何被回收" 的标准逻辑。
1.3 获取
Netty选择无锁化的方式避免线程之间的竞争,给每个线程都分配了一个对象池,acquire() 方法大致流程是:(1)优先从自己线程的对象池中获取,无任何竞争(2)若私有池为空,再从全局共享池中获取一次,这里是通过 CAS 无锁操作(3)若全局池也为空,才新建对象。
public final T get() {
// 从fastThreadLocal中获取线程私有的对象池stack
Stack<T> stack = (Stack<T>) fastThreadLocal.get();
// 从对象池获取对象
DefaultHandle<T> handle = stack.pop();
// 对象池为空,需要新建对象
if (handle == null) {
// 创建一个DefaultHandle对象
handle = stack.newHandle();
// 这里的newObject方法即上面定义RECYCLER的方法
handle.value = newObject(handle);
}
return (T) handle.value;
}
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;
this.size = size;
return ret;
}
此外还设计了FastThreadLocal替代ThreadLocal,使得线程内的存取更加高效。FastThreadLocal用一个 Object 数组存储本地变量,直接通过 index 访问数组元素,而ThreadLocal还需要哈希计算,并且哈希表的扩容、链表处理也会产生额外开销。
public abstract class MyNettyRecycler<T> {
private final FastThreadLocal<Stack<T>> fastThreadLocal = new FastThreadLocal<>() {
@Override
protected Stack<T> initialValue() {
// 初始化对象池
return new Stack<T>();
}
};
}
1.4 回收
对象的回收方法执行是从对象类开始,就比如1.2小节中的MyObject类,需要先把自身的一些属性设置成出初始化状态,再执行DefaultHandle的recycle方法,执行标准的对象池回收逻辑。
static final class DefaultHandle<T> implements Handle<T> {
// ...省略部分代码
@Override
public void recycle(T object) {
Stack<?> stack = this.stack;
stack.push(this);
}
}
void push(DefaultHandle<?> item) {
Thread currentThread = Thread.currentThread();
if (thread == currentThread) {
// 放在当前线程的Stack里面
pushNow(item);
} else {
pushLater(item, currentThread);
}
}
// 核心逻辑很简单,O(1)的时间复杂度
private void pushNow(DefaultHandle<?> item) {
if ((item.recycleId | item.lastRecycledId) != 0) {
throw new IllegalStateException("recycled already");
}
item.recycleId = item.lastRecycledId = OWN_THREAD_ID;
int size = this.size;
// 按设定的频率决定是否放入,比如执行8次pushNow方法,前7次都直接抛弃,第8次才放回elements
if (size >= maxCapacity || dropHandle(item)) {
return;
}
if (size == elements.length) {
elements = expandArray();
}
elements[size] = item;
this.size = size + 1;
}
private void pushLater(DefaultHandle<?> item, Thread thread) {
// 获取当前线程的延迟回收队列映射表
// DELAYED_RECYCLED是一个ThreadLocal,存储每个线程对应的回收队列集合
Map<Stack<?>, WeakOrderQueue> delayedRecycled = DELAYED_RECYCLED.get();
// this表示线程1创建的那个Stack对象
WeakOrderQueue queue = delayedRecycled.get(this);
// 如果队列不存在,则需要创建新线程1对应的队列
if (queue == null) {
// 如果超过最大允许数量,则放入一个空队列标记,避免重复创建
if (delayedRecycled.size() >= maxDelayedQueuesPerThread) {
delayedRecycled.put(this, WeakOrderQueue.DUMMY);
return;
}
// 为当前栈和线程分配一个新的弱引用队列
if ((queue = WeakOrderQueue.allocate(this, thread)) == null) {
return;
}
// 将新创建的队列存入映射表中
delayedRecycled.put(this, queue);
}
// 如果队列是一个空队列标记,则直接返回,不进行处理
else if (queue == WeakOrderQueue.DUMMY) {
return;
}
// 将元素添加到延迟队列的Link对象中
queue.add(item);
}
假如对象A在线程1被生成,在线程2里面执行对象A的recycle方法,会走到pushLater方法,放到线程2的WeakOrderQueue队列的自定义类Link里面。"queue = delayedRecycled.get(this)"会去拿线程1对应的WeakOrderQueue。拿到后若"queue == null",那么就说明线程2从来没有回收过线程1的对象。"queue = newWeakOrderQueue(thread)"会创建一个WeakOrderQueue,也就是去为线程2去分配一个线程1的Stack对应的WeakOrderQueue,然后通过delayedRecycled.put(this, queue)绑定线程1。(参考自cloud.tencent.com/developer/a…
这里的关键设计是 WeakOrderQueue用弱引用持有,避免内存泄漏;线程1后续操作自己的私有栈时(如 pop() 取对象),会主动从 WeakOrderQueue 中 “窃取” Handle 到自己的栈,实现跨线程回收对象的复用。可参考:www.modb.pro/db/177458和h…
-
并发控制
在上一小节文章里面,在获取、回收、定时清理不使用对象时,都要先获取到锁,而 Recycler 的设计完全规避了全局锁竞争引发的性能问题:
(1)用线程本地缓存FastThreadLocal隔离大多数操作,让高频的获取/回收无需跨线程交互
(2)在跨线程获取/回收时,用 WeakOrderQueue 和 CAS 实现无锁中转,避免锁竞争;
(3)用弱引用自动清理线程销毁后的冗余队列,无需额外维护成本。
这种设计让 Recycler 在高频对象复用场景中,既能支持多线程并发,又能保持极低的性能开销。
-
设置最大上限
在线程池里面,会有corePoolSize和maximumPoolSize限制核心线程数和存活线程的最大数量,避免线程过多导致 CPU 上下文切换频繁以及内存资源的浪费;
在 Netty 的 Recycler 中,maxCapacityPerThread 和 availableSharedCapacity是控制线程本地缓存的对象数量上限的两个重要参数,分别表示"单个线程Stack中的对象数上限"和"跨线程回收时的共享对象数上限"
maxCapacityPerThread主要防止单个线程占用过多内存
// 在Stack类中,最大容量,即maxCapacityPerThread
private final int maxCapacity;
// 当前大小
private int size;
private void pushNow(DefaultHandle<?> item) {
int size = this.size;
// 超过上限,直接丢弃
if (size >= maxCapacity || dropHandle(item)) {
return;
}
// ...
}
availableSharedCapacity用于控制跨线程对象回收的总容量,防止WeakOrderQueue占用过多内存。
当线程 A 向线程 B 的 WeakOrderQueue 中首次添加对象时,需要为线程 B 创建一个专属的 WeakOrderQueue,会先检查 “当前全局跨线程回收对象总数” 是否超过 availableSharedCapacity,若未超过,则允许添加,否则直接丢弃,避免共享缓存过度膨胀。
static boolean reserveSpaceForLink(AtomicInteger availableSharedCapacity) {
int available;
do {
available = availableSharedCapacity.get();
// 容量不足,返回false
if (available < Recycler.LINK_CAPACITY) {
return false;
}
} while(!availableSharedCapacity.compareAndSet(available, available - Recycler.LINK_CAPACITY));
return true;
}
-
对象生命周期管理
Recycler的定位是一款轻量级、高性能的对象池化工具,所以并没有复杂主动清理机制,比如给每个在池内未被使用的对象都设置一个过期时间,定时去清理过期对象,那Recycler是怎么保证不会占满内存呢?
(1)Recycler线程本地Stack中的elements数组用于存储"自己创建并回收"的对象,是强引用的关系,若 Recycler 用于线程池中的临时线程,比如业务处理线程,当线程执行完任务后销毁,其本地 Stack 中长时间未使用的对象会被 GC 自动清理,不会造成内存泄漏,依赖 JVM 垃圾回收和线程生命周期关联来间接处理,这种设计可以避免主动清理带来的额外开销。
(2)Stack中的WeakOrderQueue使用弱引用绑定线程,用于存储"自己创建并其他线程回收"的对象,弱引用关联的对象(此处是线程),若没有其他强引用(即线程被销毁了),GC 会主动回收该对象,通过弱引用绑定归属线程,WeakOrderQueue 不会阻碍线程对象的回收,GC也会清理 WeakOrderQueue 自身的内存(包括队列中的 Link 链表等),从根源上避免了线程销毁后的内存泄漏。
(3)Recycler通过maxCapacityPerThread和availableSharedCapacity两个核心参数,限制回收对象的总数量,避免无限制缓存导致内存溢出。还有interval和delayedQueueInterval两个参数,分别控制pushNow时放到elements的频率和pushLater时将对象存入WeakOrderQueue的频率。这些参数可以防止回收对象过多导致内存膨胀。
-
内存管理优化
当进行数据传输时,ByteBuf作为网络数据传输的载体,用于替代Java NIO的ByteBuffer,而ByteBuf是一个抽象类,它的实现类可以按三个维度来进行分类:一个是堆内和堆外,一个是Unsafe和非Unsafe,一个是Pooled和非Pooled(引用自:cloud.tencent.com/developer/a…
其中PooledDirectByteBuf是Netty中基于内存池(Pooled)实现的堆外内存(Direct)缓冲区,使用了Recycler对象池,当PooledDirectByteBuf被创建时,会绑定到已分配的堆外内存块;作为缓冲区,它并不需要把字节数组再转成堆内内存,直接操作堆外的字节数组即可,避免了Java堆内存与堆外内存之间的复制开销,适合高频 IO 场景。
final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final ObjectPool<PooledDirectByteBuf> RECYCLER = ObjectPool.newPool(new ObjectPool.ObjectCreator<PooledDirectByteBuf>() {
public PooledDirectByteBuf newObject(ObjectPool.Handle<PooledDirectByteBuf> handle) {
return new PooledDirectByteBuf(handle, 0);
}
});
}
三、总结
Netty 的Recycler是一款为高频对象复用场景设计的轻量级对象池,以下是对Recycler设计思想的总结:
(1)Recycler通过FastThreadLocal为每个线程分配私有Stack,让 90% 以上的获取和回收操作在单线程内完成,无需锁竞争。
(2)WeakOrderQueue通过弱引用关联线程,引用的线程销毁后自动被 GC 回收,无需手动维护跨线程队列的生命周期,减少了额外开销。
(3)跨线程回收时,WeakOrderQueue的Link节点采用分段存储,通过AtomicInteger的lazySet和compareAndSet实现无锁写入,避免了全局锁的性能瓶颈,可复用于高并发队列设计。
四、详细代码
截取部分4.1.52.Final版本的Recycler关键源码,加上一些注释方便理解,作为参考
import io.netty.util.concurrent.FastThreadLocal;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 这是Netty Recycler的完整实现,包含核心组件
*/
public abstract class MyNettyRecycler<T> {
private static final int DEFAULT_INITIAL_MAX_CAPACITY_PER_THREAD = 4 * 1024;
private static final int DEFAULT_MAX_SHARED_CAPACITY_FACTOR = 2;
private static final int DEFAULT_LINK_CAPACITY = 16;
private static final int DEFAULT_MAX_DELAYED_QUEUES_PER_THREAD = 2;
// 每个线程本地缓存可容纳的最大对象数量
private final int maxCapacityPerThread;
// 全局共享缓存的最大容量
private final int maxSharedCapacityFactor;
// 单个链表中可存储的对象数量
private final int linkCapacity;
// 每个线程可关联的延迟队列(DelayedQueue)的最大数量
private final int maxDelayedQueuesPerThread;
// 线程本地存储
private final FastThreadLocal<Stack<T>> fastThreadLocal = new FastThreadLocal<>() {
@Override
protected Stack<T> initialValue() {
return new Stack<T>(MyNettyRecycler.this, Thread.currentThread(), maxCapacityPerThread,
maxSharedCapacityFactor, linkCapacity, maxDelayedQueuesPerThread);
}
};
protected MyNettyRecycler(int maxCapacityPerThread) {
this(maxCapacityPerThread, DEFAULT_MAX_SHARED_CAPACITY_FACTOR, DEFAULT_LINK_CAPACITY, DEFAULT_MAX_DELAYED_QUEUES_PER_THREAD);
}
protected MyNettyRecycler(int maxCapacityPerThread, int maxSharedCapacityFactor,
int linkCapacity, int maxDelayedQueuesPerThread) {
this.maxCapacityPerThread = maxCapacityPerThread;
this.maxSharedCapacityFactor = maxSharedCapacityFactor;
this.linkCapacity = linkCapacity;
this.maxDelayedQueuesPerThread = maxDelayedQueuesPerThread;
}
/**
* 获取对象
*/
public final T get() {
if (maxCapacityPerThread == 0) {
return newObject(NOOP_HANDLE);
}
// 从fastThreadLocal中获取线程私有的对象池stack
Stack<T> stack = (Stack<T>) fastThreadLocal.get();
// 从对象池获取对象
DefaultHandle<T> handle = stack.pop();
// 对象池为空,需要新建对象
if (handle == null) {
handle = stack.newHandle();
handle.value = newObject(handle);
}
return (T) handle.value;
}
/**
* 创建新对象 - 由子类实现
*/
protected abstract T newObject(Handle<T> handle);
/**
* 对象句柄接口
*/
public interface Handle<T> {
void recycle(T object);
}
/**
* 默认句柄实现
*/
static final class DefaultHandle<T> implements Handle<T> {
private int lastRecycledId;
private int recycleId;
boolean hasBeenRecycled;
private Stack<?> stack;
private Object value;
DefaultHandle(Stack<?> stack) {
this.stack = stack;
}
@Override
public void recycle(T object) {
if (object != value) {
throw new IllegalArgumentException("object does not belong to handle");
}
Stack<?> stack = this.stack;
if (lastRecycledId != recycleId || stack == null) {
throw new IllegalStateException("recycled already");
}
// 执行回收操作
stack.push(this);
}
}
/**
* 线程本地栈
*/
static final class Stack<T> {
// 所属的Recycler
final MyNettyRecycler<T> parent;
// 所属线程
final Thread thread;
// 栈数组
private DefaultHandle<?>[] elements;
// 栈大小
private final int maxCapacity;
// 当前栈顶索引
private int size;
// 弱引用队列
private volatile WeakOrderQueue cursor, prev;
// 共享容量
private volatile int sharedCapacity;
// 可用共享容量
private int availableSharedCapacity;
Stack(MyNettyRecycler<T> parent, Thread thread, int maxCapacity,
int maxSharedCapacityFactor, int linkCapacity, int maxDelayedQueuesPerThread) {
this.parent = parent;
this.thread = thread;
this.maxCapacity = maxCapacity;
elements = new DefaultHandle[Math.min(maxCapacity, DEFAULT_INITIAL_MAX_CAPACITY_PER_THREAD)];
this.availableSharedCapacity = maxSharedCapacityFactor * maxCapacity;
this.maxDelayedQueuesPerThread = maxDelayedQueuesPerThread;
}
/**
* 创建新句柄
*/
DefaultHandle<T> newHandle() {
return new DefaultHandle<T>(this);
}
/**
* 弹出对象
*/
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;
this.size = size;
return ret;
}
/**
* 推入对象
*/
void push(DefaultHandle<?> item) {
// 获取当前执行线程的引用
Thread currentThread = Thread.currentThread();
// 判断当前线程是否为容器所属线程
if (thread == currentThread) {
// 同一线程则立即执行推入操作
pushNow(item);
} else {
// 不同线程则延迟执行推入操作,并传入当前线程信息
pushLater(item, currentThread);
}
}
/**
* 立即推入(当前线程)
* 直接在当前线程中执行元素推入操作,不涉及线程切换
*/
private void pushNow(DefaultHandle<?> item) {
// 检查元素是否已被回收(recycleId和lastRecycledId任一不为0表示已回收)
if ((item.recycleId | item.lastRecycledId) != 0) {
// 如果已回收则抛出异常,避免重复回收或使用已回收资源
throw new IllegalStateException("recycled already");
}
// 标记元素的回收ID为当前线程ID,标识该元素归属于当前线程
item.recycleId = item.lastRecycledId = OWN_THREAD_ID;
// 获取当前容器中元素的数量
int size = this.size;
// 检查是否超过最大容量或需要丢弃该元素
// 如果超过容量或丢弃条件成立,则不执行推入操作
if (size >= maxCapacity || dropHandle(item)) {
return;
}
// 如果当前数组已满,进行扩容操作
if (size == elements.length) {
elements = expandArray();
}
// 将元素放入数组的末尾
elements[size] = item;
// 更新容器中元素的数量
this.size = size + 1;
}
/**
* 放入延迟队列
*/
private void pushLater(DefaultHandle<?> item, Thread thread) {
// 获取当前线程的延迟回收队列映射表
// DELAYED_RECYCLED是一个ThreadLocal,存储每个线程对应的回收队列集合
Map<Stack<?>, WeakOrderQueue> delayedRecycled = DELAYED_RECYCLED.get();
// this表示线程1创建的那个Stack对象
WeakOrderQueue queue = delayedRecycled.get(this);
// 如果队列不存在,则需要创建新线程1对应的队列
if (queue == null) {
// 如果超过最大允许数量,则放入一个空队列标记,避免重复创建
if (delayedRecycled.size() >= maxDelayedQueuesPerThread) {
delayedRecycled.put(this, WeakOrderQueue.DUMMY);
return;
}
// 为当前栈和线程分配一个新的弱引用队列
if ((queue = WeakOrderQueue.allocate(this, thread)) == null) {
return;
}
// 将新创建的队列存入映射表中
delayedRecycled.put(this, queue);
}
// 如果队列是一个空队列标记,则直接返回,不进行处理
else if (queue == WeakOrderQueue.DUMMY) {
return;
}
// 将元素添加到延迟队列的Link对象中
queue.add(item);
}
/**
* 清理弱引用队列
*/
boolean scavenge() {
// 转移可以对象以及清理已过期的WeakOrderQueue
// if (scavengeSome()) {
// return true;
// }
// 重置cursor
// ......
return false;
}
/**
* 扩展数组
*/
private DefaultHandle<?>[] expandArray() {
// 保存原数组引用
DefaultHandle<?>[] oldArray = elements;
// 计算新容量:原容量左移1位(即原容量 * 2)
int newSize = oldArray.length << 1;
// 确保新容量不超过最大允许容量
if (newSize > maxCapacity) {
newSize = maxCapacity;
}
// 创建新容量的数组
DefaultHandle<?>[] newArray = new DefaultHandle[newSize];
// 将原数组中的元素复制到新数组中
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
// 返回扩容后的新数组
return newArray;
}
/**
* 是否丢弃句柄
* 根据句柄的回收状态和回收计数决定是否丢弃该元素
* @param handle 要判断的元素句柄
* @return true表示需要丢弃,false表示保留
*/
boolean dropHandle(DefaultHandle<?> handle) {
// 检查元素是否尚未被回收
if (!handle.hasBeenRecycled) {
// 递增最后回收ID,并与比例掩码进行位运算
// 此处通过位运算实现基于比例的随机丢弃策略
if ((++handle.lastRecycledId & ratioMask) != 0) {
return true; // 满足丢弃条件,返回true
}
// 标记元素为已回收状态
handle.hasBeenRecycled = true;
}
// 已回收的元素不丢弃,返回false
return false;
}
// 线程ID
private static final int OWN_THREAD_ID = (int) (Thread.currentThread().getId());
// 比例掩码
private static final int ratioMask = 7;
// 最大延迟队列数
private final int maxDelayedQueuesPerThread;
}
/**
* 弱引用队列
*/
static final class WeakOrderQueue extends WeakReference<Thread> {
static final WeakOrderQueue DUMMY = new WeakOrderQueue();
private final Head head;
private Link tail;
private final int maxCapacity;
private final Stack<?> stack;
private WeakOrderQueue next;
private WeakOrderQueue() {
super(null);
head = new Head(0);
maxCapacity = 0;
stack = null;
}
private WeakOrderQueue(Stack<?> stack, Thread thread) {
super(thread);
head = new Head(stack.availableSharedCapacity);
this.stack = stack;
this.maxCapacity = stack.maxCapacity;
this.tail = new Link();
}
/**
* 分配WeakOrderQueue
*/
static WeakOrderQueue allocate(Stack<?> stack, Thread thread) {
return new WeakOrderQueue(stack, thread);
}
/**
* 添加对象
*/
void add(DefaultHandle<?> handle) {
// 将当前队列的ID赋值为元素的最后回收ID,建立元素与队列的关联
handle.lastRecycledId = id;
// 获取当前队列的尾节点
Link tail = this.tail;
int writeIndex;
// 获取尾节点当前的写入索引,判断是否已达到节点容量上限
if ((writeIndex = tail.get()) == LINK_CAPACITY) {
// 尝试为新节点预留空间,若预留失败则直接返回(通常因容量不足)
if (!reserveSpace(stack.availableSharedCapacity, LINK_CAPACITY)) {
return;
}
// 创建新的节点作为尾节点,并更新链表结构
this.tail = tail = tail.next = new Link();
// 获取新尾节点的初始写入索引(默认为0)
writeIndex = tail.get();
}
// 将元素存入尾节点的对应索引位置
tail.elements[writeIndex] = handle;
// 清除元素与原所属栈的关联,避免线程间引用混乱
handle.stack = null;
// 原子更新尾节点的写入索引(+1),确保线程安全
tail.lazySet(writeIndex + 1);
}
/**
* 保留空间
*/
private boolean reserveSpace(int availableSharedCapacity, int space) {
return reserveSpace(head, availableSharedCapacity, space);
}
private boolean reserveSpace(Head head, int availableSharedCapacity, int space) {
return head.reserveSpace(availableSharedCapacity, space);
}
// 链接容量
private static final int LINK_CAPACITY = 16;
// 线程ID
private static final int id = (int) (Thread.currentThread().getId());
}
/**
* 队列头
*/
static final class Head {
private final AtomicInteger availableSharedCapacity;
Link link;
Head(int availableSharedCapacity) {
this.availableSharedCapacity = new AtomicInteger(availableSharedCapacity);
}
/**
* 保留空间
*/
boolean reserveSpace(int availableSharedCapacity, int space) {
return reserveSpace(this.availableSharedCapacity, availableSharedCapacity, space);
}
private boolean reserveSpace(AtomicInteger availableSharedCapacity, int availableSharedCapacity0, int space) {
int currentAvailable = availableSharedCapacity.get();
if (currentAvailable < space) {
return false;
}
return availableSharedCapacity.compareAndSet(currentAvailable, currentAvailable - space);
}
}
/**
* 链接节点
*/
static final class Link extends AtomicInteger {
private final DefaultHandle<?>[] elements = new DefaultHandle[LINK_CAPACITY];
private int readIndex;
Link next;
private static final int LINK_CAPACITY = 16;
}
// 线程本地延迟回收
private static final ThreadLocal<Map<Stack<?>, WeakOrderQueue>> DELAYED_RECYCLED =
new ThreadLocal<Map<Stack<?>, WeakOrderQueue>>() {
@Override
protected Map<Stack<?>, WeakOrderQueue> initialValue() {
return new WeakHashMap<Stack<?>, WeakOrderQueue>();
}
};
// 空操作句柄,执行recycle方法时,什么都不操作
private final Handle<T> NOOP_HANDLE = object -> {
};
}