Design and implement a thread-safe in-memory cache in Java with the following features
08:30 25 Jan 2026

Design and implement a thread-safe in-memory cache in Java with the following features:

  1. Each entry must have a time-to-live (TTL) after which it expires automatically

  2. Support put(key, value, ttl) and get(key) operations

  3. get() must run in O(1) time

  4. Multiple threads must be able to read and write concurrently

  5. Expired entries must be cleaned up without blocking normal operations

  6. Use core Java only (no external libraries)

    import java.util.concurrent.*;
    import java.util.*;
    
    public class BrokenTTLCache {
    
        class CacheItem {
            V value;
            long expiryTime;
    
            CacheItem(V value, long expiryTime) {
                this.value = value;
                this.expiryTime = expiryTime;
            }
        }
    
        private final Map cache = new HashMap<>();
        private final ScheduledExecutorService cleaner =
                Executors.newSingleThreadScheduledExecutor();
    
        public BrokenTTLCache() {
            cleaner.scheduleAtFixedRate(this::cleanUp, 0, 1, TimeUnit.MILLISECONDS);
        }
    
        public void put(K key, V value, long ttlMillis) {
            long expiryTime = System.currentTimeMillis() + ttlMillis;
            cache.put(key, new CacheItem(value, expiryTime));
        }
    
        public V get(K key) {
            CacheItem item = cache.get(key);
            if (System.currentTimeMillis() > item.expiryTime) {
                cache.remove(key);
                return null;
            }
            return item.value;
        }
    
        private void cleanUp() {
            for (K key : cache.keySet()) {
                CacheItem item = cache.get(key);
                if (System.currentTimeMillis() > item.expiryTime) {
                    cache.remove(key);
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
            BrokenTTLCache cache = new BrokenTTLCache<>();
            cache.put("X", "Bug", 1000);
            Thread.sleep(1500);
            System.out.println(cache.get("X"));
        }
    }
    \
    
java