- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我一直在阅读 Java 并发实践这本书。这绝对是一个很好的引用。我正在尝试扩展高效且可扩展的结果集缓存的最后一个示例以合并软引用。存储在我的缓存中的对象可能会变得相当大,我需要一些方法让这些对象在内存不足时进行垃圾回收,因此需要软引用。让线程安全和软引用概念发挥作用已经考验了我的极限,我需要帮助。到目前为止,这就是我的工作。我不确定这是否真的是线程安全的。任何人都可以看一下并发表评论吗?
public class RelationCollectionCache {
// properties
private final ConcurrentMap<Integer, Reference<Future<RelationCollection>>> cache =
new ConcurrentHashMap<Integer, Reference<Future<RelationCollection>>>();
private final ReferenceQueue<? super Future<RelationCollection>> queue =
new ReferenceQueue<Future<RelationCollection>>();
// constructors
public RelationCollectionCache() {
}
// methods
public RelationCollection load(final Integer id) {
Reference<Future<RelationCollection>> reference = cache.get(id);
Future<RelationCollection> future = (reference == null) ? null : reference.get();
if (future == null) {
Callable<RelationCollection> eval = new Callable<RelationCollection>() {
public RelationCollection call() throws Exception {
return compute(id);
}
};
FutureTask<RelationCollection> task = new FutureTask<RelationCollection>(eval);
reference = cache.putIfAbsent(id, new InternalSoftReference(id, task));
if (((reference == null) ? null : reference.get()) == null) {
future = task;
task.run();
}
}
try {
return future.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
private RelationCollection compute(Integer id) {
RelationCollection collection = new RelationCollection();
// lengthy computation of a large collection
return collection;
}
public RelationCollection get(Integer id) {
clean();
Reference<Future<RelationCollection>> reference = cache.get(id);
Future<RelationCollection> future = (reference == null) ? null : reference.get();
if (future == null)
return null;
try {
return future.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
public void remove(Integer id) {
clean();
cache.remove(id);
}
public void clean() {
InternalSoftReference reference = (InternalSoftReference) queue.poll();
while (reference != null) {
cache.remove(reference.id);
reference = (InternalSoftReference) queue.poll();
}
}
// internal classes
private class InternalSoftReference extends SoftReference<Future<RelationCollection>> {
private Integer id;
public InternalSoftReference(Integer id, Future<RelationCollection> future) {
super(future, queue);
this.id = id;
}
}
}
此实现在每次操作时调用 clean 方法以清除垃圾收集的引用。这也可以是一个线程,但它包含了我什至没有探索过的另一个级别的并发性。
最佳答案
这太难了。你能用MapMaker
吗来自 google-collections ?
关于java - 将 SoftReferences 添加到 "Java Concurrency in Practice"中高效且可扩展的结果缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2173113/
我的 Android 应用程序中有一个位图缓存,其中通过 SoftReference 引用位图。然而,位图被清空得太早了。缓存中最多可以有 20 个位图,如果我加载更多,GC 开始清空 SoftRef
Map> cache = new ConcurrentHashMap>(); 我已经 map 声明了一个类似于上面的 map ,我将其用作缓存。 问题是我要在将项目添加到缓存后立即对缓存执行所有操作,
我有一个创建一系列位图的应用程序。我将这些位图保存在 SoftReferences 中,以避免内存不足。我希望堆大小在开始收集我的 SoftReferences 之前增长到最大 16MB。然而,Sof
JDK 7 文档中有关于 SoftReference 的内容。 : "All soft references to softly-reachable objects are guaranteed to
我正在为我的 Android 应用程序实现缓存机制。 我使用 SoftReference,就像我发现的许多示例一样。问题是,当我在 ListView 中向上或向下滚动时,大部分 图像已经被清除。我可以
我正在为缓存实现测试 SoftReference,我发现了一个奇怪的行为: 我有一个 setName(String name) 方法,它通过 SoftReference 设置 Graph 对象的名称:
我正在使用一个搜索库,它建议将搜索句柄对象保持打开状态,因为这有利于查询缓存。随着时间的推移,我观察到缓存趋于膨胀(几百兆并不断增长)并且 OOM 开始出现。没有办法强制执行此缓存的限制,也没有计划它
看起来 Dalvik 的垃圾收集器不尊重 SoftReferences 并尽快删除它们,就像 WeakReferences 一样。我还不是 100% 确定,但尽管事实上仍有大约 3MB 的可用内存,但
我的应用程序出现了 OutOfMemoryError。当我阅读一些教程时,我开始知道,我可以通过使用 Softreference/Weakreference 来解决这个问题。但是我不知道如何使用Sof
我有一些代码使用了 SoftReference 子类的许多实例。我想测试它在所有/只有一些/没有这些引用被暂存以在 ReferenceQueue 中清除的情况下是否正常工作。对于“无”的情况,这很简单
请解释一下弱引用的用途。我通常确实了解 Java 概念,但这一个给我带来了麻烦。 我确实理解弱引用是什么,但它们的用法和性质在我的脑海中有点模糊。我无法想象一个正确的场景,其中使用弱引用成为必要。 我
编辑 到目前为止,大多数答案都集中在我错误地扩展 map 这一事实上。我已在示例代码中更正了此问题,但类型问题仍然存在,问题仍然存在。 我试图在 Scala 中实现 SoftHashMap,但遇到了类
我在这个 link 上找到了文档描述如下: 弱引用对于映射很有用,一旦它们不再被引用(从外部),应该自动删除它们的条目。 SoftReference 和 WeakReference 之间的区别在于决定
创建这么多Strong Reference会出现OOM错误是因为GC不会收集Strong Reference,但是如果没有额外的内存,GC会收集Weak Reference。所以我的问题是:我在设置
我在处理软引用和弱引用时遇到了问题。代码有一个可以切换的标志软引用和弱引用之间的所有逻辑。虽然引用很弱,但似乎为了工作正常,使用软引用我一直得到 OutOfMemoryError。这种情况发生在 Ma
使用 SoftReference 获取任何代码要进行全面测试,必须想出某种方法来测试“是的,它已被取消”的情况。人们可能或多或少地通过使用“for-test”代码路径强制引用为空来模拟这一点,但这不会
我实现了一个自定义适配器来创建一个显示与位置相关的信息的对话框(对话框的每个条目都包含一个图像、一个显示地址的文本字段和一个显示城市和国家/地区的文本字段。)在适配器的 getView (...) 方
我正在使用一个内部数据库连接池来缓存PreparedStatements。当连接返回到池中时,缓存的Statement并没有关闭。这些会在 mySQL 驱动程序中创建 OutOfMemoryExcep
我之前得出的结论是,如果您需要一个具有基于值(等于)的相等性的 SoftReference,那么设计就会很糟糕,但内部人员除外。这是继 Google Collections 和 Guava 之后,不包
我有一个包含 100 张不同图像的 ListView 。我的缓存如下所示, public class ImageCache { HashMap> myCache; .... .
我是一名优秀的程序员,十分优秀!