net.dongliu.commons.concurrent.WeakLoader Maven / Gradle / Ivy
package net.dongliu.commons.concurrent;
import net.dongliu.commons.collection.Lists;
import javax.annotation.concurrent.ThreadSafe;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
/**
* Cache which can load data into and do readonly retrieve, data may be recycled when gc.
*
* This class is thread-safe. Objects for one key may be created multi times.
* The Value produced cannot be null.
*
*
* @author dongliu
*/
@ThreadSafe
public class WeakLoader {
private final Map preDefs;
private final WeakHashMap weakMap;
private final ReadWriteLock lock;
private final Function function;
private WeakLoader(Map preDefs, Function function) {
this.preDefs = preDefs;
this.function = function;
this.weakMap = new WeakHashMap<>();
this.lock = new ReentrantReadWriteLock();
}
/**
* Create weak loader. Valus in preDefs will not be reclaimed
*/
public static WeakLoader create(Function function) {
return new WeakLoader<>(Collections.emptyMap(), function);
}
/**
* Create weak loader. Values in preDefs will not be reclaimed
*/
public static WeakLoader create(Map preDefs, Function function) {
return new WeakLoader<>(preDefs, function);
}
/**
* Create weak loader. Values in preDefs will not be reclaimed
*/
public static WeakLoader create(List extends K> preDefKeys, Function function) {
Map preDefs = Lists.toMap(preDefKeys, key -> key, function::apply);
return create(preDefs, function);
}
/**
* Get value by key
*
* @param key not null
*/
public V get(K key) {
Objects.requireNonNull(key);
V value = preDefs.get(key);
if (value != null) {
return value;
}
lock.readLock().lock();
try {
value = weakMap.get(key);
} finally {
lock.readLock().unlock();
}
if (value != null) {
return value;
}
lock.writeLock().lock();
try {
value = weakMap.get(key);
if (value != null) {
return value;
}
value = function.apply(key);
Objects.requireNonNull(value);
weakMap.put(key, value);
return value;
} finally {
lock.writeLock().unlock();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy