سؤال

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