gpt4 book ai didi

java - 将 SoftReferences 添加到 "Java Concurrency in Practice"中高效且可扩展的结果缓存

转载 作者:搜寻专家 更新时间:2023-11-01 02:55:39 24 4
gpt4 key购买 nike

我一直在阅读 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/

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