class Cache<K.V> {

    final Map<K, V> m = new HashMap<>();

    final ReadWriteLock rwl = new ReentrantReadWriteLock();
    / / read lock
    final Lock r = rwl.readLock();
    / / write locks
    final Lock w = rwl.writeLock();

    / / read the cache
    V get(K key) {
        r.lock();
        try {
            return m.get(key);
        } finally{ r.unlock(); }}/ / write cache
    V put(K key, V value) {
        w.lock();
        try {
            return m.put(key, value);
        } finally{ w.unlock(); }}Copy the code

On-demand cache

    // Cache on demand
    V getIfNeed(K key) {
        V v = null;
        / / read the cache
        r.lock();
        try {
            v = m.get(key);
        } finally {
            r.unlock();
        }
        // It exists in the cache
        if(v ! =null) {
            return v;
        }
        // Do not exist in cache, query database
        w.lock();
        try {
            // Verify again
            // Other threads may have queried the database
            v = m.get(key);
            if (v == null) {
                // Query the databasev = getFromSQL(); m.put(key, v); }}finally {
            w.unlock();
        }
        return v;
    }
Copy the code

Lock escalation

    // Lock upgrade status
    private void lockUpgrade(K key, V v) {
        / / read the cache
        r.lock();
        try {
            v = m.get(key);
            if (v == null) {
                // At this point, the read lock is not released, and the write lock is blocked, that is, the lock is not allowed to upgrade
                w.lock();
                try {
                    // Validate again and update the cache
                    // omit detailed code
                } finally{ w.unlock(); }}}finally{ r.unlock(); }}// The lock is degraded
    private void lockDegrade(K key) {
        w.lock();
        try {
            // Check the status again
            if(! cacheValid()) { V data = getFromSQL(); m.put(key, data); }// Downgrade to read lock before releasing write lock
            // Downgrade is ok
            r.lock();
        } finally {
            // Release the write lock
            w.unlock();
        }
        try {
            // The read lock is still held here
            m.get(key);
        } finally{ r.unlock(); }}private boolean cacheValid(a) {
        return false;
    }

    private V getFromSQL(a) {
        return null; }}Copy the code