1
Java 的Cleaner底层使用双向链表来保存PhantomReferences,直到它们的所指对象变得幻像可达。当Cleaner’s守护线程弹出并PhantomReference从其中删除aReferenceQueue并将其从列表中删除时,整个列表必须被锁定(删除代码在@synchronized列表中)。
相比之下,aConcurrentHashMap仍然可以提供对 s 的 O(1) 访问PhantomReference,而且还可以通过让多个清理线程PhantomReference同时从映射中删除 s(作为键)来支持并发修改。
Java 采用双向链表方法有什么原因吗?是否因为 aCleaner仅使用单个守护线程进行清理,因此缺乏并发性并不重要?或者说这个选择有更深层次的原因吗?
Java 中的 Cleaner 类使用双向链表来保存 PhantomReference 的原因主要是因为它的实现是单线程的,守护线程会周期性地清理虚引用,并且 Java 的并发框架提供了其他适用于并发环境的数据结构,比如 ConcurrentHashMap。
Cleaner
PhantomReference
ConcurrentHashMap
下面是一些可能的原因:
总的来说,选择双向链表作为 Cleaner 内部数据结构的主要原因是为了简单性和性能考虑,并且因为它是单线程的实现,不需要复杂的并发支持。