ReadWriteLock缓存刷新时防止穿透

59 阅读1分钟

缓存刷新时使用读写锁防止并发穿透到DB

public class CacheDemo {

    private HashMap<Integer , Integer> cache = new HashMap<>();
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock();
    private final Lock writeLock = lock.writeLock();


    private void put(int key , int val) {
        writeLock.lock();
        try {
            cache.put(key , val);
        }finally {
            writeLock.unlock();
        }

    }

    /**
     * 获取缓存,如果不存在,先加读锁,然后让锁升级到写锁
     * @param key
     * @return
     */
     public int get(int key) {
        readLock.lock();
        Integer val = cache.get(key);
        if (val == null) {
            readLock.unlock();
            writeLock.lock(); //因为不支持锁升级,先去释放读锁
            try {
                if (cache.containsKey(key)) {
                    return cache.get(key);
                }
                getData();
                put(key, key);
            } finally {
                writeLock.unlock();
            }
            return cache.get(key);
        }
        return -1;
    }



    public void getData(){
        System.out.println("get data!~");
    }

    public static void main(String[] args) {
        CacheDemo cacheDemo = new CacheDemo();

        for (int i = 0 ; i < 10000 ; ++i) {
            new Thread(() -> {
                cacheDemo.get(1);
            }).start();
        }
    }
}