1、背景

在计算机世界里,对于锁大家并不陌生,在现代所有的语言中几乎都提供了语言级别锁的实现,为什么我们的程序有时候会这么依赖锁呢?这个问题还是要从计算机的发展说起,随着计算机硬件的不断升级,多核cpu,多线程,多通道等技术把计算机的计算速度大幅度提升,原来同一时间只能执行一条cpu指令的时代已经过去。随着多条cpu指令可以并行执行的原因,原来不曾出现的资源竞争随着出现,在程序中的体现就是随处可见的多线程环境。比如要更新数据库的一个信息,如果没有并发控制,多个线程同时操作的话,就会出现互相覆盖的现象发生。

锁要解决的就是资源竞争的问题,也就是要把执行的指令顺序化。

在互联网背景下,电商行业是普遍都是多线程执行,并发量大。比如下单秒杀抢购商品活动,属于高并发情况,库存的保证就尤其重要了,不能出现超卖现象。程序员所要做的事情就是需要单线程执行获取库存,再减库存操作,保证数据原子性。

在多台服务器中,锁就是重点。

2、应用

我们先来介绍下单线程下的情况,假设有个商品A,库存500件,假设每次购买1件,单价1元,这样就只有是500次下单时成功的,其他都不能下单。

2.1  Store商品存储-Dictionary

数据库不存在的情况下,用Dictionary来代替

创建了Store后,主程序创建下单,单线程执行。

执行结果:

执行正常,4人不能下单。

改成多线程执行,直接出现超卖现象,其中用Task.Run 模拟多线程,其中Order(int i) i变量注意,不能直接填写i,异步中上下文不存在,因为主线程以及跑完了,再运行异步Task线程,这时变量已是最后一个被覆盖。

解决方案是重复赋值变量替换

结果:

500多的人都买了。

解决方案:

2.1.1  lock 加锁

lock很明显影响性能。

执行结果:

正常。

2.1.2  使用ConcurrentDictionary

ConcurrentDictionary 本身是线程安全的,源代码就是加了lock

执行结果符合。

2.2 用Redis分布式锁

redis是单线程运行,所以适合。原理也很简单,运用redis以下指令

1、SETNX
SETNX key val:当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
2、expire
expire key timeout:为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
3、delete
delete key:删除key
在使用Redis实现分布式锁的时候,主要就会使用到这三个命令。

原理如下:

1、先获取redis锁,设置一个随机字符串

执行了805次,看下输出最后数量有没有小于0

结果显示0,正确,没超卖

.net Redis分布式锁,Dictionary,ConcurrentDictionary 介绍的更多相关文章

  1. 分布式-技术专区-Redis分布式锁实现-第一步

    承接前面一篇Redis分布式锁的原理介绍 https://www.cnblogs.com/liboware/p/11921759.html 我们针对于实现方案进行接下来上篇进行重新的规划和定义以及完善 ...

  2. Redis分布式锁 (图解-秒懂-史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  3. 死磕 java同步系列之redis分布式锁进化史

    问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:R ...

  4. redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  5. spring boot redis分布式锁

    随着现在分布式架构越来越盛行,在很多场景下需要使用到分布式锁.分布式锁的实现有很多种,比如基于数据库. zookeeper 等,本文主要介绍使用 Redis 做分布式锁的方式,并封装成spring b ...

  6. Redis分布式锁的正确实现方式

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  7. Redis分布式锁---完美实现

    这几天在做项目缓存时候,因为是分布式的所以需要加锁,就用到了Redis锁,正好从网上发现两篇非常棒的文章,来和大家分享一下. 第一篇是简单完美的实现,第二篇是用到的Redisson. Redis分布式 ...

  8. 关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

  9. 【分布式缓存系列】集群环境下Redis分布式锁的正确姿势

    一.前言 在上一篇文章中,已经介绍了基于Redis实现分布式锁的正确姿势,但是上篇文章存在一定的缺陷——它加锁只作用在一个Redis节点上,如果通过sentinel保证高可用,如果master节点由于 ...

随机推荐

  1. c#中几种数据结构

    数组型: Array:内存连续分配,长度不可变,可索引访问. ArrayList:早期版本使用,非泛型,类型不安全,如果元素数据类型不同可考虑使用. List<>:泛型,可变长度,内存连续 ...

  2. 【PL/SQL】PLSQL Developer注册码

    [12.0.7] product code: 4vkjwhfeh3ufnqnmpr9brvcuyujrx3n3le serial Number:226959 password: xs374ca

  3. <String> 49 87

    49. Group Anagrams class Solution { public List<List<String>> groupAnagrams(String[] str ...

  4. Spring Boot 2.2.0,性能提升+支持Java13

    随着 Spring Framework 5.2.0 成功发布之后,Spring Boot 2.2 也紧跟其后,发布了第一个版本:2.2.0.下面就来一起来看看这个版本都更新了些什么值得我们关注的内容. ...

  5. [TJOI2019]唱,跳,rap,篮球(生成函数,组合数学,NTT)

    算是补了个万年大坑了吧. 根据 wwj 的题解(最准确),设一个方案 \(S\)(不一定合法)的鸡你太美组数为 \(w(S)\). 答案就是 \(\sum\limits_{S}[w(S)=0]\). ...

  6. [LeetCode] 410. Split Array Largest Sum 分割数组的最大值

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

  7. [LeetCode] 33. Search in Rotated Sorted Array 在旋转有序数组中搜索

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  8. mtd-utils编译安装过程

    git clone git://git.infradead.org/mtd-utils.git cd mtd-utils apt install -y libssl-dev libzlb libzst ...

  9. 初始socket模块和巧解粘包问题

    1.什么是socket? 两个进程如果需要进行通讯最基本的一个前提能够唯一的标示一个进程,在本地进程通讯中我们可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大 ...

  10. FontForge 汉化教程

    引用 :http://www.sucaijishi.com/2018/articles_0815/258.html FontForge是一款免费字库编辑工具,官方暂不提供简体中文,本文汉化方法在201 ...