SoftReference可能用于值(等于)相等

时间:2010-02-12 07:12:56

标签: java concurrency guava concurrenthashmap

我之前得出结论,如果你需要一个基于值(等于)相等的SoftReference,那么一个设计不好,除了这个内容。这是关注Google Collections和Guava不包括这样的类。但是我遇到了一个我认为可以使用这样一个对象的问题。

我们在视觉效果渲染场中有一个资产管理系统,其中100个进程运行相同的作业,只有它渲染的帧数不同。我们有一个Oracle数据库需要记录所有使用的资产。在中间层资产管理系统中,我们可以使用HashSet来记录是否将插入到Oracle中的对象,而不是使用相同的插入来冲击Oracle,其中只有一个将从所有作业中获得成功。

我可以使用过期的Google MapMaker,但我不想担心过期是正确的,我们提供的是几小时和几天的渲染。使用等于等于的SoftReference听起来是一种更好的方式,因此JVM将自动管理垃圾收集。

对于我想用带垃圾收集的ConcurrentHashMap解决的其他问题,我会在HashMap中使用强引用作为获取equals()相等性的关键,并使用SoftReference作为值,以便JVM可以垃圾收集内容,但在这种情况下,值无关紧要,我没有值包装在SoftReference中放在那里。因此,使用带有equals()的SoftReference似乎可以解决问题。

对此还有其他建议吗?

3 个答案:

答案 0 :(得分:1)

在大多数情况下,如果您想对Google收藏集使用软引用,请致电

MapMaker.softValues()

使用强键但是软值,查找将使用相等性,并且当内存紧张时,键值对将被垃圾收集。

答案 1 :(得分:1)

由于没有ConcurrentHashSet使用软引用,因此只有两种方法:

1。)您使用ConcurrentHashMap

的方法
  • 覆盖equals
  • 中的hashCodeSoftReference
  • equalshashCode内部仅使用SoftReference#get
  • 访问该对象
  • SoftReference作为键,将任何对象作为值(不允许为null)
  • 如果在访问hashCode或equals时引用变为陈旧,请将引用添加到删除队列以频繁删除已死的密钥。
  • 通过containsKey
  • 检查包含

2。)使用ConcurrentMultimap<Integer, Set<SoftReference<RepLookupEntry>>并使用hashCode作为键,并使用同步的SoftReferences作为值。当您获得hashCode点击时,请检查所有SoftReferences的内容是否相等。不是很漂亮,我同意并且很难同步。

如果我在你的位置,我根本不会使用SoftReferences,而是使用ConcurrentHashMap来保持对POJO的强引用。每次新元素到达时,也将它放在ConcurrentLinkQueue中。如果队列增长超过某个限制,则开始从HashMap中删除元素。

答案 2 :(得分:0)

我认为这门课程将满足您的需求:

import java.util.*;
import java.lang.ref.*;

public class SoftSet<T> extends AbstractSet<T> {

  private final WeakHashMap<T,SoftReference<T>> data = new WeakHashMap<T,SoftReference<T>>();

  public boolean add(T t) {
    return null == data.put(t, new SoftReference<T>(t));
  }

  public boolean remove(Object o) {
    return null != data.remove(o);
  }

  public boolean contains(Object o) {
    return data.containsKey(o);
  }

  public Iterator<T> iterator() {
    return data.keySet().iterator();
  }

  public int size() {
    return data.size();
  }

  public void clear() {
    data.clear();
  }

  public boolean removeAll(Collection<?> c) {
    return data.keySet().removeAll(c);
  }

  public boolean retainAll(Collection<?> c) {
    return data.keySet().retainAll(c);
  }
}

这应该起作用的方式是,一旦作为值的软引用被清除,那么该值仅可以弱到达,并且可以从内部地图中删除该键。