Sobes.tech
Senior

How to ensure thread safety of the implemented LRU cache?

sobes.tech AI

Answer from AI

To ensure thread safety of an LRU cache in Java, several approaches can be used:

  1. Method synchronization — wrap all methods that modify the cache state in synchronized blocks or declare them synchronized, so that only one thread can perform operations at a time.

  2. Using ConcurrentHashMap and ConcurrentLinkedDeque — for storing data and access order, which helps avoid locks at the entire cache level.

  3. Using ready-made thread-safe data structures — for example, LinkedHashMap with an overridden removeEldestEntry method can be wrapped in Collections.synchronizedMap, but additional synchronization of iterations is needed.

  4. Using ReentrantLock — a more flexible locking mechanism that allows controlling access and avoiding performance issues.

Example with synchronized methods:

public class ThreadSafeLRUCache<K, V> {
    private final int capacity;
    private final LinkedHashMap<K, V> cache;

    public ThreadSafeLRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new LinkedHashMap<K, V>(capacity, 0.75f, true) {
            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
                return size() > ThreadSafeLRUCache.this.capacity;
            }
        };
    }

    public synchronized V get(K key) {
        return cache.get(key);
    }

    public synchronized void put(K key, V value) {
        cache.put(key, value);
    }
}

This approach guarantees that get and put operations will not be executed simultaneously from different threads, preventing race conditions.