基于ReadWriteLock的全局安全缓存实现

55 阅读2分钟

文章目录


前言

在项目中有时候是需要用到缓存的,其实常见的有:

  1. spring cache
  2. 本地线程副本ThreadLocal
  3. 内存Memchache
  4. 可持久化的redis

上述缓存都有用过,使用的场景各不相同


一、为什么要有缓存?

缓存就是为了加速查询性能,提高系统/接口响应时间,对于系统优化,性能提升有很大帮助;
缓存的危害:

  1. 常见的面试题: 缓存穿透 雪崩
  2. 缓存一致性问题
  3. …等等有很多缓存方面的问题,在实际项目中需要我们去解决

然而不能因噎废食,不能因为缓存的种种危害就不去用,我们要在合适的业务场景选择合适的缓存;

例如:

  • spring cache : 查询性能优化
  • 本地线程副本ThreadLocal: 多租户等用户信息缓存
  • 内存Memchache: 查询性能优化,缓存数据工具
  • 可持久化的redis: 查询性能优化,

二、实现一个线程安全的缓存工具类

/**
 * 全局安全缓存类
 *
 * @author fulin
 * @since 2023/5/17 15:07
 */
public class CacheUtil {

    static Map<String, Object> map = new HashMap<>();

    static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    static Lock readLock = readWriteLock.readLock();
    static Lock writeLock = readWriteLock.readLock();

    private CacheUtil() {
    }

    public static void put(String key, Object value) {
        writeLock.lock();
        try {
            map.put(key, value);
        } finally {
            writeLock.unlock();
        }
    }

    public static Object get(String key) {
        readLock.lock();
        try {
            return map.get(key);
        } finally {
            readLock.unlock();
        }
    }

    public static void clear() {
        writeLock.lock();
        try {
            map.clear();
        } finally {
            writeLock.unlock();
        }
    }

    public static void remove(String key) {
        if (!map.containsKey(key)) {
            return;
        }
        writeLock.lock();
        try {
            map.remove(key);
        } finally {
            writeLock.unlock();
        }
    }

}

此类用读写锁互斥,作为线程安全的缓存,读读不互斥,读写互斥,写写互斥;


总结

在spring项目中,其实用spring cache 可以解决大部分问题,当有多租户的情况,或者缓存各自的用户信息的时候,可以采用本地线程变量副本处理,当然如果用上述工具类,也会使项目中的缓存使用更佳灵活;

本文转自 jimolvxing.blog.csdn.net/article/det…,如有侵权,请联系删除。