Question

I am creating my own cache object that will serve several threads, this is an assignment so i am not allowed to use packages and jar that are out there. I am trying to figure out how to invalidate all of them at the same time. I have a date structure that contains a bunch of entries, where the key is an integer and the value is a boolean. When a worker have a miss, it adds the value to its cache. I have several other threads that update this data structure, and once they update it they should invalidate all the other worker threads that have this cache, only if the have this entry in their cache.

For example say that there are two workers T1 cache has 1,true T2 cache has 3,true

and the data structure has 1,true; 2,true; 3 true. Now the updater changes 3, false. So it should check T1 and not do anything and should check T2 and change it. However, this two checks should happen somehow at the same time, because if I have a case in which T1 cache has 3,true T2 cache has 3,true T1 may be invalidated, while T2 was not invalidated yet, and we have an inconsistent behavior.

any ideas? my cache code is

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

public class workerCache {
    @SuppressWarnings("rawtypes")
    LinkedHashMap cache;
    ReentrantLock lock;

    @SuppressWarnings("serial")
    public <T> workerCache(final int maxEntries) {
        this.lock = new ReentrantLock();

        this.cache = new LinkedHashMap<T, T>(maxEntries + 1) {
            @SuppressWarnings("rawtypes")
            protected boolean removeEldestEntry(Map.Entry eldest) {
                return size() > maxEntries;
            }
        };
    }

    @SuppressWarnings("unchecked")
    public <T> void setEntry(T key, T value) {

        lock.lock();
        try {
            cache.put(key, value);
        } finally {
            lock.unlock();
        }
    }

    public <T> void invalidateEntry(T key) {
        lock.lock();
        try {
            cache.remove(key);
        } finally {
            lock.unlock();
        }

    }

    @SuppressWarnings("unchecked")
    public <T> T get(T key) {
        lock.lock();
        try {
            return (T) this.cache.get(key);
        } finally {
            lock.unlock();
        }
    }
Was it helpful?

Solution

It sounds like you're imagining that three threads "T1", "T2", "T3" all have their own copy of workerCache that they need to keep in sync. Is this right?

If so, I would say that's a problem. Instead of three caches (one for each thread), how about one cache shared between all threads?

That way, everybody sees the same data all the time b/c there's only one copy of the data (since there is only one cache). If you invalidate an entry from T1 then everybody "sees" that invalidation at the same time -- as a consequence of there being only one cache.

If you have three threads all updating the same key, then the last one into the cache wins. I'm not sure if that's an issue for you or not.

Am I anywhere approaching the problem?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top