3

我正在学习使用 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 的状态会不同。

现在假设我想要一个定时器任务来清理缓存,比如说它会清理一半的缓存。我的问题是我上面的代码是否确保这两个操作(放置缓存和添加 lru)对于清理任务来说是原子的?我可以做如下的事情:

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里放什么?

非常感谢!!!

4

2 回答 2

2

我的问题是我上面的代码是否确保这两个操作(放置缓存和添加 lru)对于清理任务来说是原子的?

是(假设清洁任务在不同的线程中)

我应该在XXX里放什么?

相同的缓存对象例如:synchronized (cache) {同步应该发生在同一个锁(对象)上

如果它们对您的情况有用,您还可以探索 java 中的其他原子类:atomic package

于 2013-01-02T03:52:14.303 回答
0

在您的情况下,您将在 XXX 处同步缓存,但是,我建议您将同步putgetLru方法作为替代方法。

于 2013-01-02T03:52:11.370 回答