Gan*_*alf 7 java algorithm caching ehcache
所以这是我试图解决的问题 - 我有一个带有两个整数字段的对象我想要缓存
public class MyObject {
int x;
int y;
....
}
Run Code Online (Sandbox Code Playgroud)
现在该字段x是我主要匹配的 - 但是可能存在重复,在这种情况下我想要回到第二个字段(因此this.x = that.x和this.y = that.y).y只能是25个不同的值.现在我知道我可以将两者合并为String并将其用作缓存键,但是我必须尝试x+[25 possible values]确定它是否不在缓存中 - 使缓存未命中非常昂贵.我正在考虑尝试将a存储List<Integer>为字段的缓存值x,然后如果它们超过1,则迭代列表并查找匹配项y.
现在,如果我使用a ConcurrentList(或者如果我关心重复项,那么我们现在就忽略它)将多个线程能够添加到它,然后将其放回缓存而没有竞争条件?是否有可能Ehcache可能会将两个不同的列表对象返回到两个线程,然后当他们将新值添加到列表并尝试将其放回缓存时,我可能得到不确定的结果?您是否看到了构建此缓存的更好方法?
编辑:我很欣赏下面的答案,但每个人似乎都错过了重点.这会有用吗?Ehcache实际上可以为同一个cacheKey返回两个不同的对象(比如在调用期间对象是否在磁盘上并且它被序列化两次,每次调用一次).
您可以获得List(或任何Serializable)的两个不同实例!试试这个:
public static void main(final String[] args) throws Exception {
final Cache cache = CacheManager.getInstance().getCache("smallCache");
final List<String> list = new ArrayList<String>();
cache.put(new Element("A", list));
/* We put in a second element. Since maxElementsInMemory="1", this means
* that "A" will be evicted from memory and written to disk. */
cache.put(new Element("B", new ArrayList<String>()));
Thread.sleep(2000); // We need to wait a bit, until "A" is evicted.
/* Imagine, the following happens in Thread 1: */
final List<String> retrievedList1 =
(List<String>) cache.get("A").getValue();
retrievedList1.add("From Thread 1");
/* Meanwhile, someone puts something in the cache: */
cache.put(new Element("C", new ArrayList<String>()));
Thread.sleep(2000); // Once again, we wait a bit, until "A" is evicted.
/* Now the following happens in Thread 2: */
final List<String> retrievedList2 =
(List<String>) cache.get("A").getValue();
retrievedList2.add("From Thread 2");
cache.put(new Element("A", retrievedList2));
/* Meanwhile in Thread 1: */
cache.put(new Element("A", retrievedList1));
/* Now let's see the result: */
final List<String> resultingList =
(List<String>) cache.get("A").getValue();
for (final String string : resultingList) {
System.out.println(string);
} /* Prints only "From Thread 1". "From Thread 2" is lost.
But try it with maxElementsInMemory="3", too!! */
CacheManager.getInstance().shutdown();
}
Run Code Online (Sandbox Code Playgroud)
我在ehcache.xml中使用了以下内容:
<cache name="smallCache"
maxElementsInMemory="1"
eternal="true"
overflowToDisk="true"
diskPersistent="true"
maxElementsOnDisk="200"
memoryStoreEvictionPolicy="LRU"
transactionalMode="off"
>
</cache>
Run Code Online (Sandbox Code Playgroud)
一种解决方案可能是使用Explicit Locking,它似乎也适用于独立(非Terracotta)缓存(从ehcache 2.1开始).
另一种解决方案是只有一个可以修改List的线程.如果您有多个可以修改它的线程,并且您没有在缓存上使用锁定,那么您可以获得您描述的完全不确定的结果!