本篇文章小编给大家分享一下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拿到我们实际使用的对象
忍者必须死34399账号登录版 最新版v1.0.138v2.0.72
下载勇者秘境oppo版 安卓版v1.0.5
下载忍者必须死3一加版 最新版v1.0.138v2.0.72
下载绝世仙王官方正版 最新安卓版v1.0.49
下载Goat Simulator 3手机版 安卓版v1.0.8.2
Goat Simulator 3手机版是一个非常有趣的模拟游
Goat Simulator 3国际服 安卓版v1.0.8.2
Goat Simulator 3国际版是一个非常有趣的山羊模
烟花燃放模拟器中文版 2025最新版v1.0
烟花燃放模拟器是款仿真的烟花绽放模拟器类型单机小游戏,全方位
我的世界动漫世界 手机版v友y整合
我的世界动漫世界模组整合包是一款加入了动漫元素的素材整合包,
我的世界贝爷生存整合包 最新版v隔壁老王
我的世界MITE贝爷生存整合包是一款根据原版MC制作的魔改整