基本锁介绍

1、分类

乐观锁:
	在select的时候不会加锁,是基于程序实现的,所以不会存在死锁的情况。
	适用于读多写少的场景(写的并发量相对不高),可以提高系统的吞吐量。
	因为如果写多的话,乐观锁会有很大机率更新失败,需要不断的自旋执行查找和更新操作。
	自旋的时候会一直占用CPU,会耗费大量的CPU资源。


悲观锁:
	在select的时候就会加锁,采用先加锁后处理的模式,虽然保证了数据处理的安全性,但也会阻塞其他线程的写操作。
	悲观锁适用于写多读少的场景,因为拿不到锁的线程,会将线程挂起,交出CPU资源,可以把CPU给其他线程使用,提高了CPU的利用率。


锁分类:
	悲观锁:具有强烈的独占和排他特性,在整个数据处理过程中,将数据处于锁定状态。适合于写比较多,会阻塞读操作。
	乐观锁:采取了更加宽松的加锁机制,大多是基于数据版本( Version )及时间戳来实现。。适合于读比较多,不会阻塞读

独占锁:互斥锁、排他锁:保证在任一时刻,只能被一个线程独占排他持有。synchronized、ReentrantLock
共享锁:可同时被多个线程共享持有。CountDownLatch到计数器、Semaphore信号量 

可重入锁:又名递归锁。同一个线程在外层方法获取锁的时候,在进入内层方法时会自动获取锁。
不可重入锁:

公平锁: 有优先级的锁,先来先得,谁先申请锁就先获取到锁
非公平锁: 无优先级的锁,后来者也有机会先获取到锁

自旋锁: 当线程尝试获取锁失败时(锁已经被其它线程占用了),无限循环重试尝试获取锁
阻塞锁: 当线程尝试获取锁失败时,线程进入阻塞状态,直到接收信号后被唤醒。在竞争激烈情况下,性能较高

读锁: 共享锁
写锁: 独占排他锁

偏向锁:一直被一个线程所访问,那么该线程会自动获取锁
轻量级锁:CAS):当锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁,
	其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能。
重量级锁:当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候(10次),
	还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让他申请的线程进入阻塞,性能降低。
以上其实是synchronized的锁升级过程

表级锁: 对整张表加锁,加锁快开销小,不会出现死锁,但并发度低,会增加锁冲突的概率
行级锁: 是mysql粒度最小的锁,只针对操作行,可大大减少锁冲突概率,并发度高,但加锁慢,开销大,会出现死锁

2、具体锁实现:

1、jvm:

ReentrantLock悲观的独占的可重入的可公平可不公平锁
		synchronized悲观的独占的可重入的非公平锁
			无锁 --> 偏向锁(同一个线程再次获取锁) --> 轻量级锁(自旋) --> 重量级锁

2、mysql:

select ... for update:悲观的独占的
select ... lock in share mode

3、jvm:ReentrantLock + synchronized

	1.单个jvm实例 单机
	2.必须单例
	3.与事务并存问题
	总之,不适合于保证数据库数据可靠性

4、mysql:

	1.直接更新时判断。在更新中判断库存是否大于0 
	update table set surplus = (surplus - buyQuantity) where id = 1 and (surplus - buyQuantity) > 0 ;
		解决jvm锁多例模式锁失效问题 及 事务共存问题
		锁范围控制:条件字段必须创建索引;查询条件必须具体的值
		同一个商品有多个库存时,无法解决。
		无法记录库存变化前后的状态
	2.悲观锁:select ... for update
		库存操作要统一:不能有的操作是select ... for update 而有的操作是普通的select
		死锁风险:多条记录时,加锁顺序要一致
		阻塞及性能问题
	3.乐观锁:version 或者 时间戳(CAS思想)
		ABA问题
		失败需要重试,高并发情况下性能不高
		读写分离情况下导致乐观锁不可靠

5、zookeeper

客户端:ZooKeeper原生客户端、ZkClient、Curator
	前两个客户端参照:https://blog.csdn.net/qq_42349306/article/details/118209298
读操作和设置监听事件之间是有原子性的

阻塞公平锁:
	1.接收到请求时,在/locks节点下创建一个临时序列化节点
	2.判断自己是不是/locks节点下最下的节点:是则获取到锁,不是则监听前一个节点
	3.获取到锁,处理完业务逻辑后,通过delete删除当前节点释放锁。监听当前节点的下一个节点收到通知,重复第二步。

Curator分布式锁源码解读:https://blog.csdn.net/qq_41432730/article/details/123389670

你可能感兴趣的:(锁,锁)