Better synchronization in ConcurrentMapCache
Issue: SPR-13810
This commit is contained in:
parent
9b9f3714ae
commit
3096888c7d
|
@ -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 {
|
||||||
* 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 {
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
|
||||||
@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
|
||||||
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
|
||||||
|
|
||||||
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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue