java - 如何等到 WeakHashMap 更新?
问题描述
除了固定超时之外,还有其他方法可以知道WeakHashMap在密钥变得弱可访问后何时更新其条目?
例如,这段代码使对键的强引用无效,除非添加超时,否则仍会打印条目在映射中。
WeakHashMap<Integer, Integer> map = new WeakHashMap<>();
Integer i = 1000;
map.put(i, 1);
System.out.println(map.size()); // prints 1
i = null;
System.gc();
//Thread.sleep(0);
System.out.println(map.size()); // without sleep prints 1, with sleep prints 0
有没有更优雅的方法可以知道 WeakReferences 何时完成更新?
解决方案
我不认为有一个好的方法可以做到这一点。有几个问题:
从 中清除陈旧条目
WeakHashMap
是一种内部机制,它涉及ReferenceQueue
实现私有的。您需要打破封装才能访问该queue
字段。好的,这是可能的,但是理论上你会让你的代码特定于 Java 版本。
WeakHashMap
除了自身 之外,没有什么好的方法可以检查队列。ReferenceQueue
只提供三个公共操作poll()
:remove()
和remove(time_out)
。这些都会从队列中删除一个元素(如果有的话)。但是,如果除WeakHashMap
删除元素之外的任何其他内容,该元素将不会被处理。这实际上意味着您无法在不“破坏”队列的情况下检测到队列中何时有东西。
好的,所以你也可以打破抽象
ReferenceQueue
来访问它的head
字段。即使您执行上述操作,您仍然需要轮询该
ReferenceQueue.head
字段以检测队列何时变为非空并再次为空。处理队列的代码
WeakHashMap
不会自发运行。(没有更干净的线程。)它实际上是get
在put
某些size
东西clear
对WeakHashMap
. 详细信息可能因版本而异。这意味着您的代码试图检测的“事件”只会在您调用
get
. 因此,如果您只想get
在删除条目后调用,则时间依赖项中有一个“循环”。
最后,不能保证调用System.gc()
会立即(或根本)运行,或者它会检测到给定的不可访问对象是不可访问的1。即使它确实检测到这一点,也不能保证它WeakReference
会及时被破坏。
所以你不应该通过可预测的地图清理来编写你的应用程序来依赖这些东西。(如果这个只是单元测试的真正用例,我认为这不值得花时间在这上面。sleep
解决方法很好......假设它足够可靠。)
1 - 例如,如果对象已被使用并且System.gc()
调用仅触发次要收集,则该对象不会被检测为不可访问。
推荐阅读
- wso2 - WSO2 Micro Integration 7.X 中的人工任务
- c# - 加入一维数组以覆盖具有多条记录的 CSV 文件
- python - 单击没有 ID 或唯一名称 selenium python 的下载按钮
- python - 摆脱 Ticker Formatter 中的小数
- generics - 如何在 rust 宏中扩展多个特征边界?
- javascript - 无法使用 socket.io 发送发布请求
- python - Python 和 GStreamer:视频会议应用
- python - 使用其他数组python的排序对数组列表进行排序
- python - 为什么在进行分配时属性属性没有被右侧替换?
- python - 何时使用 fit_transform 和 transform?