netty 的 Recycler
2021-04-25 12:29
标签:other expec rect last next edr ace cst support netty 是用 Recycler 实现对象池。 每个线程有一个 ThreadLocalMap 变量,ThreadLocalMap 本质是一个哈希表,用 index + 1 来避免槽冲突,键是 ThreadLocal 变量,值是尖括号里的对象。netty 里面大量使用 ThreadLocal,目的是减少多线程之间锁竞争。 DefaultHandle 封装了对象,是直接存放在 Stack 中的元素 Stack 是最直接的对象池,用数组实现的栈,存放 DefaultHandle 如果我们获取一个对象,需要调用 用完对象之后,归还 那么,归还到 WeakOrderQueue 中的元素,啥时候用到呢 把 WeakOrderQueue 中的元素移到 Stack 中 netty 的 Recycler 标签:other expec rect last next edr ace cst support 原文地址:https://www.cnblogs.com/allenwas3/p/12229532.html// 每个线程一个 Stack,用作对象池
private final FastThreadLocal
// 每个线程有一个 Map,存储其他线程的 Stack -> WeakOrderQueue 对
private static final FastThreadLocal
private static final class DefaultHandle
private static final class Stack
public final T get() {
// 没有启用对象池
if (maxCapacityPerThread == 0) {
return newObject((Handle
public void recycle(Object object) {
if (object != value) {
throw new IllegalArgumentException("object does not belong to handle");
}
// DefaultHandle 绑定的 stack
Stack> stack = this.stack;
if (lastRecycledId != recycleId || stack == null) {
throw new IllegalStateException("recycled already");
}
stack.push(this);
}
void push(DefaultHandle> item) {
Thread currentThread = Thread.currentThread();
// 当前线程持有该 stack
if (threadRef.get() == currentThread) {
// 直接入栈
pushNow(item);
} else {
// 归还的对象不是由当前线程获取的
pushLater(item, currentThread);
}
}
private void pushLater(DefaultHandle> item, Thread thread) {
if (maxDelayedQueues == 0) {
// We don‘t support recycling across threads and should just drop the item on the floor.
return;
}
// 当前线程的 Map
Map
DefaultHandle
boolean transfer(Stack> dst) {
Link head = this.head.link;
if (head == null) {
return false;
}
if (head.readIndex == LINK_CAPACITY) {
if (head.next == null) {
return false;
}
head = head.next;
this.head.relink(head);
}
final int srcStart = head.readIndex;
int srcEnd = head.get();
final int srcSize = srcEnd - srcStart;
if (srcSize == 0) {
return false;
}
final int dstSize = dst.size;
final int expectedCapacity = dstSize + srcSize;
if (expectedCapacity > dst.elements.length) {
final int actualCapacity = dst.increaseCapacity(expectedCapacity);
srcEnd = min(srcStart + actualCapacity - dstSize, srcEnd);
}
if (srcStart != srcEnd) {
final DefaultHandle[] srcElems = head.elements;
final DefaultHandle[] dstElems = dst.elements;
int newDstSize = dstSize;
for (int i = srcStart; i ) {
DefaultHandle> element = srcElems[i];
if (element.recycleId == 0) {
element.recycleId = element.lastRecycledId;
} else if (element.recycleId != element.lastRecycledId) {
throw new IllegalStateException("recycled already");
}
srcElems[i] = null;
if (dst.dropHandle(element)) {
// Drop the object.
continue;
}
element.stack = dst;
dstElems[newDstSize ++] = element;
}
if (srcEnd == LINK_CAPACITY && head.next != null) {
// Add capacity back as the Link is GCed.
this.head.relink(head.next);
}
head.readIndex = srcEnd;
if (dst.size == newDstSize) {
return false;
}
dst.size = newDstSize;
return true;
} else {
// The destination stack is full already.
return false;
}
}
上一篇:认识html,css
下一篇:从头认识js-js的发展历史