gpt4 book ai didi

java - 如果存在强引用,保证返回现有对象的线程安全对象池?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:40:20 24 4
gpt4 key购买 nike

我正在尝试扩展 Clojure 语言以将 ACI 保证的引用扩展为 ACID 保证的 dref(持久引用)。 API 是简单地调用 (dref key value) , 其中key是要在底层数据存储中使用的键的字符串(在我当前的实现中是 BDB JE),并且 value是 dref 应初始化为的对象。如果key已存在于数据库中,将使用存储的值。

可以使用相同的 key 创建多个 dref,并且它们需要同步,即,如果一个具有 key “A”的 dref 参与了使用 (ensure) 写入或读取的事务,所有其他具有键“A”的 dref 必须在事务上同步:读锁和写锁必须用于对涉及这些 dref 的事务强加顺序。从更大的意义上讲,虽然可能有多个内存中的 dref 具有相同的键,但所有这些具有该键的 dref 都是一个逻辑对象。

出于显而易见的原因,简单地确保使用单个具体的内存中 dref 实现此单个逻辑 dref 要容易得多。这样就没有什么可以同步的了。我该怎么做?

显而易见的答案是使用以 key 为键的对象池。然后 Clojure 将调用静态 getInstance(key,value)如果存在,则从池中检索方法,如果不存在,则创建它并填充池。这种方法的问题在于,没有简单的方法让 Clojure 在完成时释放对象。内存泄漏城市。我必须确保不会收集任何对其具有强引用的对象,并且它们存在于池中。如果池丢失了对仍在使用的逻辑 dref 的引用,那将是灾难性的,因为另一个进程可能会使用相同的 key 创建一个新的 dref,并且它与具有相同 key 的其他 dref 在事务上是不安全的。

所以我需要一些版本的 WeakHashMap或使用非强引用的东西(我更喜欢 SoftReference s 因为 GC 有点不情愿)。所以:

  1. 如果我使用 HashMap<String,SoftReference<DRef>> ,如果收集了条目 (SoftReference) 的值,我如何确保映射将逐出条目?某种守护线程?
  2. 如何使池对于 GC 是线程安全的?或者我不必担心,因为 GC 在 SoftReference 运行级别,我的守护线程将是在 Map 运行的线程水平?
  3. 在相关说明中,如何确保守护线程正在运行?有什么方法可以让它停止而不会抛出一个异常,如果未被捕获,这个异常会使整个 JVM 崩溃?如果是这样,我该如何监控并在需要时启动一个新的?

最佳答案

您尝试过 google-collections 吗?

他们有一个 MapMaker,可以提供带有软/弱键和值的并发 HashMap 的变体。一个问题是弱键/软键的相等性是身份,这很烦人,但如果键是字符串,则可能不会太多。

我相信其他库可以做到这一点(org.apache.commons.collections 但我从未使用过它们)。

关于java - 如果存在强引用,保证返回现有对象的线程安全对象池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3752957/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com