高并发之_锁

提起高并发, 就不得不提 "锁"的概念

目录:

初识: 锁

锁的实现原理

锁的优化方向



初识: 锁

关于锁,有以下几个问题
1) 什么是锁?

2) 锁是干什么用的?

3) 现成的锁如何使用?



锁的实现原理

关于锁的原理, 有以下几个问题

1) 锁的实现流程是什么?

2) 锁为什么能保证数据安全?



锁的优化方向

1) 锁会有什么弊端么?

1) 锁该如何优化?





1) 什么是锁?
: 抽象与生活中的概念,即用锁来锁住的大门,一般情况下除了有钥匙的人之外,其他人都进不去.
在编程中也是如此, 由于多线程,产生了高并发, 相当于几十号人往一个茅坑里冲,如果不锁门,那么少说也会有几个人同时挤入, 然后拉的到处都是. 那么这个茅坑就废了 (如果这种情况你还敢去,本博主愿称你位最强)

2) 锁是干什么用的?
在编程中 “锁” 就是防止多个线程同时在同时 (此处的同时也可是是运行某一段业务逻辑的时间) 操作一个数据
在生活里 “锁” 就是防止多个人冲一间厕所.

假若 削减库存
最简单的逻辑是:
选择 --> 订单 --> 扣减库存 --> 支付 --> …
那么在 减少库存的时候, 首先拿到库存数,然后在当前的数量上减去用户购买的个数.
假设一个用户下订单,到订单完成. 需要1秒中的处理时间, 那么 60个用户就需要60秒的处理时间, 也就是说 第61个客户需要等 1830秒,将近30分钟 才能等到系统开始处理他的订单, 而越往后越恐怖.
此时的解决方案之一就是开启一个线程,相当于有两个线程在处理当前事务那么详单与 1秒处理两笔订单. 客户只要等待15分钟就可以了.同理线程开的越多处理速度越快
那么如果在获取库存的时候出现并发导致拿到的库存数一致, 那么就相当于同一间商品卖出去两次, 会导致卖出的商品大于库存的情况.
此时只需要使用锁把 获取存款数和扣减库存数的代码包裹起来, 形成一个小房间, 当一个线程拿到钥匙进入其中并再度把门锁上, 当线程出来之前,别的线程都进不去. 如此方可保证库存正常

3) 现成的锁如何使用?
在编程语言中对于锁的概念都会有封装, 一般在比较流行的编程语言都会对锁进行语法封装.
而如果没有线程的锁,那么只能自己实现锁的机制. 然后根据你自己的规则来使用了.





1) 锁的实现流程是什么?
实现锁 必须得有两个前提条件:
1) 共享
2) 互斥
流程如下:
当线程A 拿到锁C 的时候值为true,那么线程A 将锁置为false 然后进入 锁包裹的代码块中. 在线程A 出代码块之前 锁C的值一直都会是false
线程B 拿到锁C的时候 发现 锁C的值为false, 那么就无法进入 代码块此时只能沉睡 or 死循环判断 锁C的值 什么时候 为 true就 跳出去.

在以上的流程中 线程A和线程B 都能拿到锁C, 这就是 共享
线程A先拿到锁C就可以进入, 线程B在拿到锁C时线程A没有运行完毕那么 就无法进入 这就是 互斥

2) 锁为什么能保证数据安全?

因为只要锁的实现逻辑没有问题, 功能正常,在锁包裹的代码块中同时只能有一个线程运行,也就在局部不存在多线程的状况, 如此数据自然不会出错





1) 锁会有什么弊端么?
锁的弊端很明显, 将业务某一块 由多线程并发变成单线程串行,那么由多线程带来的性能在这一块是不存在的, 会导致性能的下降,如果锁住的代码块过多会导致性能的严重下降

1) 锁该如何优化?
关于锁的优化可以从两点入手:
1) 锁的覆盖范围
2) 锁的实现方式
最理想的状态莫过于 “无锁化”, 即不使用线程挂起,唤醒机制 来保证当前的数据在高并发下的安全性

在高并发下只有三种可能性:
1) 只有一个线程运行当前代码块
2) 有多个线程交替运行当前代码块
3) 有多个线程并发运行当前代码块

发布了41 篇原创文章 · 获赞 225 · 访问量 8726

猜你喜欢

转载自blog.csdn.net/weixin_43843042/article/details/104560053