最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Netty分布式从recycler对象回收站获取对象过程代码解析
时间:2022-06-29 01:51:22 编辑:袖梨 来源:一聚教程网
本篇文章小编给大家分享一下Java互相关联的实体无限递归问题解决方法,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
从对象回收站中获取对象
从回收站获取对象
public static void main(String[] args){ User user1 = RECYCLER.get(); user1.recycle(); User user2 = RECYCLER.get(); user2.recycle(); System.out.println(user1==user2); }
这个通过Recycler的get方法获取对象, 我们跟到get方法中:
public final T get() { if (maxCapacityPerThread == 0) { return newObject((Handle) NOOP_HANDLE); } Stack stack = threadLocal.get(); DefaultHandle handle = stack.pop(); if (handle == null) { handle = stack.newHandle(); handle.value = newObject(handle); } return (T) handle.value; }
首先判断maxCapacityPerThread是否为0, maxCapacityPerThread代表stack最多能缓存多少个对象, 如果缓存0个, 说明对象将一个都不会回收
这个通过调用newObject创建一个对象, 并传入一个NOOP_HANDLE, NOOP_HANDLE是一个handle, 我们看其定义:
private static final Handle NOOP_HANDLE = new Handle() { @Override public void recycle(Object object) { } };
这里的recycle方法是一个空实现, 代表不进行任何对象回收
回到get方法中
我们看第二步
Stack
这里通过FastThreadLocal对象拿到当前线程的stack, 有关FastThreadLocal获取对象的逻辑之前小节剖析过, 这里不再赘述
获取stack之后, 从stack中pop出一个handle, 这个handle做用我们稍后分析
如果取出的对象为null, 说明当前回收站内没有任何对象, 通常第一次执行到这里对象还没回收, 这里就会是null, 这样则会通过stack.newHandle()创建一个handle
创建出来的handle的value属性, 通过我们重写的newObject方法进行赋值, 也就是我们demo中的user
我们跟进newHandle方法
DefaultHandlenewHandle() { return new DefaultHandle (this); }
这里创建一个DefaultHandle对象, 并传入this, 这里的this是当前stack
跟到DefaultHandle的构造方法中:
DefaultHandle(Stack> stack) { this.stack = stack; }
这里初始化了stack属性
DefaultHandle中还有个value的成员变量
private Object value;
这里的value就用来绑定回收的对象本身
回到get方法中:
分析handle, 我们回到上一步:
DefaultHandlehandle = stack.pop();
我们分析从stack中弹出一个handle的逻辑
跟到pop方法中
DefaultHandlepop() { 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大于零, 则size进行自减, 代表取出一个元素
然后通过size的数组下标的方式将handle取出
之后将当前下标设置为null
最后将属性recycleId, lastRecycledId, size进行赋值
recycleId和lastRecycledId我们会在之后的小节进行分析
回到get方法中:
public final T get() { if (maxCapacityPerThread == 0) { return newObject((Handle) NOOP_HANDLE); } Stack stack = threadLocal.get(); DefaultHandle handle = stack.pop(); if (handle == null) { handle = stack.newHandle(); handle.value = newObject(handle); } return (T) handle.value; }
无论是从stack中弹出的handle, 还是创建的handle, 最后都要通过handle.value拿到我们实际使用的对象
相关文章
- 《原神》5.2卡池抽取建议 11-14
- 《原神》5.2版本新怪物介绍 11-14
- 《原神》希诺宁增伤触发方法 11-14
- 《原神》循音觅奇活动入口 11-14
- 《原神》循音觅奇兑换码获取方法 11-14
- 《原神》花羽会活动飞行技巧介绍 11-14