Java多线程编程 - 原子操作

时间:2013-01-02 03:31:54

标签: java multithreading concurrent-programming

我正在学习使用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?

非常感谢!!!

2 个答案:

答案 0 :(得分:2)

  

我的问题是我上面的代码是否确保这两个操作(放入缓存并添加lru)对于clean任务看起来是原子的?

是(假设清洁任务在不同的主题中)

  

我应该把什么放在XXX?

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

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

答案 1 :(得分:0)

在您的情况下,您将在XXX处同步缓存,但是,我建议您查看将 put getLru 方法同步为另类。