前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于ReadWriteLock读写锁实现的缓存

基于ReadWriteLock读写锁实现的缓存

作者头像
张申傲
发布2020-09-03 15:57:10
4550
发布2020-09-03 15:57:10
举报
文章被收录于专栏:漫漫架构路
代码语言:javascript
复制
package william.pattern;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Supplier;

/**
 * @Author: ZhangShenao
 * @Date: 2019/5/22 10:22
 * @Description:基于读写锁实现的简单的缓存
 * 1.读操作之间可并发执行
 * 2.读写、写写操作之间互斥
 * 3.根据key获取不同的锁,减小锁粒度
 */
public class SimpleCache<K, V> {
    private Map<K, V> cache = new HashMap<>();
    private Map<K, ReadWriteLock> locks = new ConcurrentHashMap<>();

    public V get(K key, Supplier<V> optionsWhenMiss) {
        V value;
        try {
            //加读锁
            acquireLock(key, false);

            //查询缓存
            value = cache.get(key);
        } finally {
            //释放读锁
            releaseLock(key, false);
        }

        //如果缓存命中,则直接返回
        if (value != null) {
            return value;
        }

        //缓存未命中,加写锁,执行optionsWhenMiss操作
        try {
            acquireLock(key, true);
            //这里再进行一次缓存的查询,避免高并发场景下,多线程竞争写锁,导致数据的重复查询
            value = cache.get(key);
            if (value == null) {
                value = optionsWhenMiss.get();
            }
        } finally {
            //释放写锁
            releaseLock(key, true);
        }
        return value;
    }

    public void put(K key, V value) {
        //加写锁
        try {
            acquireLock(key, true);
            cache.put(key, value);
        } finally {
            //释放写锁
            releaseLock(key, true);
        }
    }

    private void acquireLock(K key, boolean write) {
        Lock lock = lockForKey(key, write);
        lock.lock();
    }

    private void releaseLock(K key, boolean write) {
        Lock lock = lockForKey(key, write);
        lock.unlock();

    }

    private Lock lockForKey(K key, boolean write) {
        ReadWriteLock rw = locks.computeIfAbsent(key, k -> new ReentrantReadWriteLock());
        return write ? rw.writeLock() : rw.readLock();
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/05/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档