I am trying to implement a high performance thread-safe caching. Here is the code I have implemented. I don't want any on demand computing. Can I use cache.asMap() and retrieve the value safely? Even if the cache is set to have softValues?
import java.io.IOException;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class MemoryCache {
private static MemoryCache instance;
private Cache<String, Object> cache;
private MemoryCache(int concurrencyLevel, int expiration, int size) throws IOException {
cache = CacheBuilder.newBuilder().concurrencyLevel(concurrencyLevel).maximumSize(size).softValues()
.expireAfterWrite(expiration, TimeUnit.SECONDS).build();
}
static public synchronized MemoryCache getInstance() throws IOException {
if (instance == null) {
instance = new MemoryCache(10000, 3600,1000000);
}
return instance;
}
public Object get(String key) {
ConcurrentMap<String,Object> map =cache.asMap();
return map.get(key);
}
public void put(String key, Object obj) {
cache.put(key, obj);
}
}
Values are automatically loaded by the cache, and are stored in the cache until either evicted or manually invalidated. Implementations of this interface are expected to be thread-safe, and can be safely accessed by multiple concurrent threads.
The Guava Cache is an incremental cache, in the sense that when you request an object from the cache, it checks to see if it already has the corresponding value for the supplied key. If it does, it simply returns it (assuming it hasn't expired).
Guava provides a very powerful memory based caching mechanism by an interface LoadingCache<K,V>. Values are automatically loaded in the cache and it provides many utility methods useful for caching needs.
Hazelcast is for distributed caching, meaning many services share the same cache, whereas Guava/Caffeine is a local cache per each service (not shared). It depends on your business requirements.
Guava contributor here:
Yes, that looks just fine, although I'm not sure what the point is of wrapping the cache in another object. (Also, Cache.getIfPresent(key)
is fully equivalent to Cache.asMap().get(key)
.)
If you want high performance, why don't you instanciate the Cache statically instead of using a synchronized getInstance()?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With