c# .NET 高级编程 高并发必备技巧 - 锁
锁 最为常见的应用就是 高并发的情况下,库存的控制。本次只做简单的单机锁介绍。
直接看代码:
每请求一次库存-1. 假如库存1000,在1000个人请求之后,库存将变为0。
public int Reduce0()
{
int r = 0;
string key = "stock";
string stock = Rds.cli.Get(key);
int.TryParse(stock, out r);
if (r > 0)
{
r--;
Rds.cli.Set(key, r);
}
else
{
throw new Exception("库存用尽!");
}
return r;
}
本次测试使用Jmeter进行测试。先初始化库存为1000。

Jmeter 设置如下,一个线程请求1000次,再去查看库存刚好为0,没有任何问题:


调整一下测试参数,5个人同时请求,各请求200次。再去查看库存


发现请求后,还有279的库存。明明请求了1000次。但是还有279的库存,明显不对。
造成次问题的原因很简单,就是在库存还没完全减的情况下,有另外一个、或多个线程同时发出了请求,而库存只减少了1
只要还有库存,就可以继续请求,到了库存完全为0的时候,已经超过1000个人进行了请求。与实际库存不符合。
为了解决这个问题。我们简单调整一下代码:
private static object lck = new object();
[HttpGet]
public int Reduce1()
{
lock(lck)
{
int r = 0;
string key = "stock";
string stock = Rds.cli.Get(key);
r = int.Parse(stock);
if (r > 0)
{
r--;
Rds.cli.Set(key, r);
}
else
{
throw new Exception("库存用尽!");
}
return r;
}
}
声明一个静态变量,然后再方法体内 使用lock。调整代码后,再次进行测试:

发现 请求1000次后,库存为0。调整测试参数 100人*10次。测试结果依然为0。
到此为止,问题解决。
但是,实际应用场景中,高并发的应用,都会多机分布式部署。分布式部署要怎么解决?大家思考一下。
c# .NET 高级编程 高并发必备技巧 - 锁的更多相关文章
- 高级java高并发,高性能,分布式,高可用,负载均衡,系统架构实战
java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战 视频课程包含: ...
- C#编程高并发的几种处理方法
并发(英文Concurrency),其实是一个很泛的概念,字面意思就是“同时做多件事”,不过方式有所不同.在.NET的世界里面,处理高并发大致有以下几种方法: 1,异步编程 异步编程就是使用futur ...
- Qt高级编程 高清PDF+源|网盘下载地址附提取码|
书籍作者:Mark Summerfield(马克 . 萨默菲尔德)(英) 书籍译者:闫锋欣内容简介:本书是一本阐述Qt高级编程技术的书籍.本书以工程实践为主旨,是对Qt现有的700多个类和上百万字 ...
- Java高并发实战,锁的优化
锁优化 这里的锁优化主要是指 JVM 对 synchronized 的优化. 自旋锁 互斥同步进入阻塞状态的开销都很大,应该尽量避免.在许多应用中,共享数据的锁定状态只会持续很短的一段时间.自旋锁的思 ...
- 【多线程与高并发】- synchronized锁的认知
synchronized锁的认知 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目录 s ...
- golang网络编程高并发
1 golang写服务器不需要epoll吗 golang写服务器不需要在用reactor模式的epoll了,因为golang的协程非常廉价,可以并发开启成千上完个协程. 一个协程占用内存大概2KB左右 ...
- java并发编程(1) --并发基础及其锁的原理
引言 多线程的知识点是一个庞大的体现,对此也是一知半解.一直想系统的深入的学习多线程的知识,奈何一直没有找到机会,好吧,其实就是懒.最近在项目中接触到一个多并发的项目,在项目中踩了无数的坑.在此下定决 ...
- UNIX环境高级编程——线程同步之互斥锁、读写锁和条件变量(小结)
一.使用互斥锁 1.初始化互斥量 pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;//静态初始化互斥量 int pthread_mutex_init( ...
- 高并发redis分布式锁
1.方法一 2方法二
- 海量并发的无锁编程 (lock free programming)
最近在做在线架构的实现,在线架构和离线架构近线架构最大的区别是服务质量(SLA,Service Level Agreement,SLA 99.99代表10K的请求最多一次失败或者超时)和延时.而离线架 ...
随机推荐
- 2021-12-28:给定一个二维数组matrix,matrix[i][j] = k代表: 从(i,j)位置可以随意往右跳<=k步,或者从(i,j)位置可以随意往下跳<=k步, 如果matrix[i]
2021-12-28:给定一个二维数组matrix,matrix[i][j] = k代表: 从(i,j)位置可以随意往右跳<=k步,或者从(i,j)位置可以随意往下跳<=k步, 如果mat ...
- sql server 系统表详细说明
sql server 系统表详细说明 sysaltfiles 主数据库 保存数据库的文件syscharsets 主数据库字符集与排序顺序sysconfigures 主数据库 配置选项 syscurco ...
- Strings must be encoded before hashing
Strings must be encoded before hashing 当我们将字符串传递给 hash 算法时,会出现 "TypeError: Strings must be enco ...
- Redis 高级特性 Redis Stream使用
Redis Stream 简介 Redis Stream 是 Redis 5.0 版本新增加的数据结构. Stream从字面上看是流类型,但其实从功能上看,应该是Redis对消息队列(MQ,Messa ...
- IT入门深似海,入门到放弃你学废了嘛
我一直觉得IT行业 程序员行业.甚至觉得程序员人群 是一个特殊存在的群体. 入门到放弃,是真的,IT门槛高嘛. 其实吧,IT编程门槛,是有的,但是对于感兴趣的,想学习IT编程同学来说,也是一件容易事情 ...
- 驱动开发:内核实现SSDT挂钩与摘钩
在前面的文章<驱动开发:内核解析PE结构导出表>中我们封装了两个函数KernelMapFile()函数可用来读取内核文件,GetAddressFromFunction()函数可用来在导出表 ...
- Linux 调用约定
函数调用约定是对函数调用时如何传递参数的一种约定.关于它的约定有许多种,下面我们分 别从内核接口和用户接口两方面介绍32位和64位Linux的调用约定. 一.内核接口 x86-32系统调用约定 ...
- 【后端面经-数据库】MySQL的存储引擎简介
目录 MySQL的存储引擎 0. 存储引擎的查看和修改 1. MyISAM 2. InnoDB 3. MEMORY 4. MERGE 5. 总结 6. 参考博客 MySQL的存储引擎 mysql主要有 ...
- docker构建FreeSWITCH编译环境及打包
操作系统 :CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 Docker版本:23.0.6 FreeSWITCH这种比较复杂的系统,使用容器部署是比较方便的,今天 ...
- StencilJs学习之组件装饰器
stenciljs 可以方便的构建交互式组件 支持以下装饰器 component state prop watch method element event listen Component 装饰器 ...