I am on my way learning multi-thread programming with Java. Here is a confusion I got.

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
}

}

Here is some very simple cache with a least recently used record (lru). Obviously I need to make these two operations atomic. Otherwise it's very likely the state of cache and lru would be different.

Now assume I want to have a timer task to clean the cache, say it will clean half the cache. My question is does my code above ensure these two operations (put cache and add lru) appear atomic to the clean task? Can I do something like below:

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());
            }
        }
    }
}

And what should I put in XXX?

Thanks a lot!!!

有帮助吗?

解决方案

My question is does my code above ensure these two operations (put cache and add lru) appear atomic to the clean task?

yes (assuming cleaning task is in different thread)

And what should I put in XXX?

the same cache object for example: synchronized (cache) { a the synchronization should happen on the same lock (object)

you can also explore other atomic classes in java if they could be useful in your case: atomic package

其他提示

In your case, you would synchronize on cache at XXX, however, I suggest you look at synchronizing the put and getLru methods as an alternative.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top