实现可固定大小的本地缓存


核心实现

继承LinkedHashMap实现简单的LRU算法 | Feliks

使用LRU淘汰策略,重写LinkedHashMap中的removeEldestEntry()方法

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
    return false;
}

重写为:

@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
    return size() > size;
}

在进行put操作的时候会判断,如果为true就会删除最老的那个entry

代码

MyCache

package com.feliks.core;

import java.util.LinkedHashMap;
import java.util.Map;

public class MyCache<K, V> extends LinkedHashMap<K, V> {
    private int size;
    private Object lock;

    public MyCache(int size, Object lock) {
        super((int) (size * 1.4f), 0.75f, true);
        this.size = size;
        if (lock != null) {
            this.lock = lock;
        } else {
            this.lock = this.getClass();
        }
    }

    public MyCache setLock(Object lock) {
        this.lock = lock;
        return this;
    }

    public MyCache setSize(int size) {
        this.size = size;
        return this;
    }


    /**
     * 重写LinkedHashMap的removeEldestEntry方法
     * 在Put的时候判断如果为true就会删除最老的
     *
     * @param eldest
     */
    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > size;
    }

    /**
     * 当其他线程试图访问被synchronized修饰的代码块时会被阻塞,
     * 只有当前拿到锁的进程可以访问代码块
     *
     * @param key
     */
    public Object getValue(K key) {
        synchronized (lock) {
            return get(key);
        }
    }

    /**
     * @param key
     * @param value
     */
    public void putValue(K key, V value) {
        synchronized (lock) {
            put(key, value);
        }
    }

    public boolean removeValue(K key) {
        synchronized (lock) {
            Object remove = remove(key);
            return remove != null;
        }
    }

    public boolean removeAll() {
        synchronized (lock) {
            clear();
            return true;
        }
    }
}

引导类MyCacheBs

package com.feliks.core;

public class MyCacheBs<K, V> {
    private int size = Integer.MAX_VALUE;
    private Object lock;

    private MyCacheBs() {
    }

    /**
     * 创建对象实例
     *
     * @return
     */
    public static MyCacheBs newBuilder() {
        return new MyCacheBs();
    }

    /**
     * 设置大小限制
     *
     * @param size
     * @return
     */
    public MyCacheBs setSize(int size) {
        this.size = size;
        return this;
    }

    /**
     * @param lock
     * @return
     */
    public MyCacheBs setLock(Object lock) {
        this.lock = lock;
        return this;
    }

    public MyCache build() {
        MyCache<K, V> myCache = new MyCache<>(size, lock);
        return myCache;
    }
}

测试

import com.feliks.core.MyCache;
import com.feliks.core.MyCacheBs;

import java.util.HashMap;

public class testMyCache {
    public static void main(String[] args) {
        MyCache cache = MyCacheBs
                .newBuilder()
                .setSize(3)
                .setLock(testMyCache.class)
                .build();

        cache.putValue("1", "test1");
        cache.putValue("2", "test2");
        cache.putValue("3", "test3");
        System.out.println(cache);

        cache.putValue("1", "test1");
        System.out.println(cache.getValue("1"));
        System.out.println(cache);

        cache.putValue("3", "test3");
        System.out.println(cache.getValue("3"));
        System.out.println(cache);

        cache.putValue("4", "test4");
        System.out.println(cache.getValue("4"));
        System.out.println(cache);
    }
}

测试结果

image-20240420170734920


文章作者: Feliks
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Feliks !
评论
  目录