zoukankan      html  css  js  c++  java
  • 双重检测优化与加锁操作redis

    今天,学习了公司大佬的代码,又又又发现了一些让我迷惑的写法... ...

    在我对redis浅显的认知中,redis是单线程多路io复用的,那么既然是单线程的话,我想应该大概也许可能不涉及到线程安全的问题吧。

    但是,今天在大佬的代码中,发现了一个读写redis的方法加了锁,方法做的事情很简单,开始我并不理解操作redis为什么要加锁,直到在网上找了一些资料之后,才明白可能存在读到脏数据的问题。

    比如有两个线程都要从redis中读取一个值,将其加10,再回写回redis,数据初始值为0。

    我们期望得到的结果是20,但最后可能结果为10。

    假设,第一个线程读取数据0,将其加10,但并未来得及写入redis,然后时间片就结束了。此时,轮到第二个线程读取数据,那么获取到的数据依然为0,将其加10,依然没有写入redis时间片就结束了。

    现在,线程一将redis中的值改为10,线程二依然会将redis中的值改为10,最终结果为10。

    大佬的代码中使用了缓存来降低数据库的压力,按照我之前的理解,在一个读取数据的方法中,首先读取缓存信息,如果获取不到数据,则读取数据库信息并写入缓存。

    但大佬的思路是,首先读取缓存信息,如果获取不到数据,则再次读取缓存信息,如果还是获取不到数据,则读取数据库信息并写入缓存。

    刚开始很迷惑,这样做的意义何在?忽然之间,想到了单例模式的一种实现,双重检测,其中的一层检测是为了提高效率。由于项目中采用了多线程,所以在第一个线程没有从缓存中获取到数据之后,有可能其他线程已经完成了读取数据库写入缓存的操作,也就是说,第一个线程再次得到时间片的时候,就没有必要访问数据库获取数据了。

  • 相关阅读:
    Linux下crontab详解
    Linux下mail/mailx命令发送邮件
    Linux下Mysql数据库备份
    Linux远程备份—ftp方式、NFS方式
    Fedora 17安装NFS
    Linux下vsftp服务器—上传、下载
    Linux中Kill进程的N种方法
    Linux命令执行顺序— ||和&&和;
    C#中override和overload的区别
    C#中派生类调用基类构造函数用法分析
  • 原文地址:https://www.cnblogs.com/wxdmw/p/13404157.html
Copyright © 2011-2022 走看看