我正在学习使用Java进行多线程编程。这是我的困惑。
class Cache<K, V> {
private ConcurrentMap<K, V> cache;
private ConcurrentLinkedQueue<K> lru;
public Cache () {
// initiate cache and lru
}
public put (K key, V value) {
// some pre-processing
synchronized (this) {
cache.put(key, value);
lru.add(key);
}
// some post-processing
}
}
这是一个非常简单的缓存,其中包含最近最少使用的记录(lru)。显然我需要使这两个操作成为原子。否则,缓存和lru的状态很可能会有所不同。
现在假设我想要一个计时器任务来清理缓存,说它会清理一半的缓存。我的问题是我的代码是否确保这两个操作(put cache和add lru)对于clean任务看起来是原子的?我可以做以下的事情:
class CleanTask {
Cache cache; // the reference of Cache
public void run () {
// some pre-processing
for (int i = 0; i < n; i++) { // Just suppose I need remove n element
synchronized (XXX) {
cache.getCache().remove(cache.getLru().poll());
}
}
}
}
我应该把什么放在XXX?
非常感谢!!!
答案 0 :(得分:2)
我的问题是我上面的代码是否确保这两个操作(放入缓存并添加lru)对于clean任务看起来是原子的?
是(假设清洁任务在不同的主题中)
我应该把什么放在XXX?
相同的缓存对象,例如:synchronized (cache) {
a同步应该在同一个锁(对象)上发生
如果它们在您的案例中有用,您还可以探索java中的其他原子类:atomic package
答案 1 :(得分:0)
在您的情况下,您将在XXX处同步缓存,但是,我建议您查看将 put 和 getLru 方法同步为另类。