
net.sf.cglib.core.internal.LoadingCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cglib-jdk9 Show documentation
Show all versions of cglib-jdk9 Show documentation
cglib is a powerful, high performance and quality Code Generation Library, It is used to extend JAVA classes and implements interfaces at runtime.
The newest version!
package net.sf.cglib.core.internal;
import java.util.concurrent.*;
public class LoadingCache {
protected final ConcurrentMap map;
protected final Function loader;
protected final Function keyMapper;
public static final Function IDENTITY = new Function() {
public Object apply(Object key) {
return key;
}
};
public LoadingCache(Function keyMapper, Function loader) {
this.keyMapper = keyMapper;
this.loader = loader;
this.map = new ConcurrentHashMap();
}
@SuppressWarnings("unchecked")
public static Function identity() {
return IDENTITY;
}
public V get(K key) {
final KK cacheKey = keyMapper.apply(key);
Object v = map.get(cacheKey);
if (v != null && !(v instanceof FutureTask)) {
return (V) v;
}
return createEntry(key, cacheKey, v);
}
/**
* Loads entry to the cache.
* If entry is missing, put {@link FutureTask} first so other competing thread might wait for the result.
* @param key original key that would be used to load the instance
* @param cacheKey key that would be used to store the entry in internal map
* @param v null or {@link FutureTask}
* @return newly created instance
*/
protected V createEntry(final K key, KK cacheKey, Object v) {
FutureTask task;
boolean creator = false;
if (v != null) {
// Another thread is already loading an instance
task = (FutureTask) v;
} else {
task = new FutureTask(new Callable() {
public V call() throws Exception {
return loader.apply(key);
}
});
Object prevTask = map.putIfAbsent(cacheKey, task);
if (prevTask == null) {
// creator does the load
creator = true;
task.run();
} else if (prevTask instanceof FutureTask) {
task = (FutureTask) prevTask;
} else {
return (V) prevTask;
}
}
V result;
try {
result = task.get();
} catch (InterruptedException e) {
throw new IllegalStateException("Interrupted while loading cache item", e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
throw ((RuntimeException) cause);
}
throw new IllegalStateException("Unable to load cache item", cause);
}
if (creator) {
map.put(cacheKey, result);
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy