java缓存为什么要加锁_使用缓存时对于加锁的思考(* * * * *)

突然发现之前写的自己实现XXX的话题不是很被大众关注,可能是真的写的不行,也可能是大多都是一些吃了饭没事做瞎写的一些东西,大家都没兴趣,之后可能会尽量写一些真正实用的东西,大家一起学习。言归正传,促使我研究这个话题的原因是在工作中遇到需要自己实现多级缓存的情况。比如在springboot中我们虽然可以随意替换缓存技术,可以使用redis也可以使用ehcache,但是据我所知,这些缓存默认都是只能使用一种。假设现在我需要同时使用ehcache和redis,其中ehcache做本地的第一级缓存。这里忽略可能用到的mybatis,hibernate那些操作数据库的orm框架的缓存,单独只考虑应用层面的缓存。当然在已经有springboot,ehcache,redis的情况下,通过自定义注解,切面拦截,组合ehcache和redis的两级缓存,其实并不是很困难。难点只在于细节部分,比如怎么让自己定义的注解和切面可以被springboot中的缓存注解开关@EnableCaching控制,又比如多点部署时怎么让ehcache本地缓存和redis集中式缓存实现同步,当然也有使用缓存的时候怎么加锁的问题。本话题重点讨论,在缓存使用时的加锁问题。

其实当我们刚开始学java的线程中同步工具时,我们就接触到synchronized,锁,读写锁等。其中在api文档的ReentrantReadWriteLock类里有一个例子,专门演示了读写锁,在一个缓存对象中的使用的例子如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

class CachedData {

Object data;

volatile boolean cacheValid;

ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

void processCachedData() {

rwl.readLock().lock();

if (!cacheValid) {

// Must release read lock before acquiring write lock

rwl.readLock().unlock();

rwl.writeLock().lock();

// Recheck state because another thread might have acquired

// write lock and changed state before we did.

if (!cacheValid) {

data = ...

cacheValid = true;

}

// Downgrade by acquiring read lock before releasing write lock

rwl.readLock().lock();

rwl.writeLock().unlock(); // Unlock write, still hold read

}

use(data);

rwl.readLock().unlock();

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

里面的读写锁,double check,锁降级等用的炉火纯青自是不用说的,我当时也是对此记忆犹新,如获至宝啊,感觉这段代码很适合装B,然后我在我的缓存实现代码里也准备这么玩,当我把这段代码复制过去,改成我需要的逻辑后,我就发现了问题。瞬间感觉这要是这么玩,可能装B不成那个啥的。然后我搜了搜网上别人的这种玩法,想看看别人是不是也有这种尴尬。然后搜索出来一大把如下面代码(百度搜索:java读写锁实现缓存)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值