提交 3096888c 编写于 作者: S Stephane Nicoll

Better synchronization in ConcurrentMapCache

Issue: SPR-13810
上级 9b9f3714
...@@ -59,7 +59,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { ...@@ -59,7 +59,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
* @param name the name of the cache * @param name the name of the cache
*/ */
public ConcurrentMapCache(String name) { public ConcurrentMapCache(String name) {
this(name, new ConcurrentHashMap<Object, Object>(256), true); this(name, new ConcurrentHashMap<>(256), true);
} }
/** /**
...@@ -69,7 +69,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { ...@@ -69,7 +69,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
* values for this cache * values for this cache
*/ */
public ConcurrentMapCache(String name, boolean allowNullValues) { public ConcurrentMapCache(String name, boolean allowNullValues) {
this(name, new ConcurrentHashMap<Object, Object>(256), allowNullValues); this(name, new ConcurrentHashMap<>(256), allowNullValues);
} }
/** /**
...@@ -141,20 +141,14 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { ...@@ -141,20 +141,14 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
return (T) get(key).get(); return (T) get(key).get();
} }
else { else {
synchronized (this.store) { return (T) fromStoreValue(this.store.computeIfAbsent(key, r -> {
if (this.store.containsKey(key)) {
return (T) get(key).get();
}
T value;
try { try {
value = valueLoader.call(); return toStoreValue(valueLoader.call());
} }
catch (Exception ex) { catch (Exception ex) {
throw new ValueRetrievalException(key, valueLoader, ex); throw new ValueRetrievalException(key, valueLoader, ex);
} }
put(key, value); }));
return value;
}
} }
} }
......
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -44,9 +44,9 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests<ConcurrentMapCac ...@@ -44,9 +44,9 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests<ConcurrentMapCac
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
nativeCache = new ConcurrentHashMap<Object, Object>(); this.nativeCache = new ConcurrentHashMap<>();
cache = new ConcurrentMapCache(CACHE_NAME, nativeCache, true); this.cache = new ConcurrentMapCache(CACHE_NAME, this.nativeCache, true);
cache.clear(); this.cache.clear();
} }
@Override @Override
...@@ -84,9 +84,9 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests<ConcurrentMapCac ...@@ -84,9 +84,9 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests<ConcurrentMapCac
public void testNonSerializableContent() { public void testNonSerializableContent() {
ConcurrentMapCache serializeCache = createCacheWithStoreByValue(); ConcurrentMapCache serializeCache = createCacheWithStoreByValue();
thrown.expect(IllegalArgumentException.class); this.thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Failed to serialize"); this.thrown.expectMessage("Failed to serialize");
thrown.expectMessage(this.cache.getClass().getName()); this.thrown.expectMessage(this.cache.getClass().getName());
serializeCache.put(createRandomKey(), this.cache); serializeCache.put(createRandomKey(), this.cache);
} }
...@@ -96,15 +96,15 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests<ConcurrentMapCac ...@@ -96,15 +96,15 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests<ConcurrentMapCac
String key = createRandomKey(); String key = createRandomKey();
this.nativeCache.put(key, "Some garbage"); this.nativeCache.put(key, "Some garbage");
thrown.expect(IllegalArgumentException.class); this.thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Failed to deserialize"); this.thrown.expectMessage("Failed to deserialize");
thrown.expectMessage("Some garbage"); this.thrown.expectMessage("Some garbage");
serializeCache.get(key); serializeCache.get(key);
} }
private ConcurrentMapCache createCacheWithStoreByValue() { private ConcurrentMapCache createCacheWithStoreByValue() {
return new ConcurrentMapCache(CACHE_NAME, nativeCache, true, return new ConcurrentMapCache(CACHE_NAME, this.nativeCache, true,
new SerializationDelegate(ConcurrentMapCacheTests.class.getClassLoader())); new SerializationDelegate(ConcurrentMapCacheTests.class.getClassLoader()));
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册