乐观锁、悲观锁、行锁、页锁、表锁、共享锁、排它锁、互斥锁归纳总结

有次面试被问到数据库锁,回答的比较含糊,相关概念分类没有理解透彻,特作此篇。
先上图:在这里插入图片描述

乐观锁与悲观锁

乐观锁:取数据时总是认为不会被修改,因此不上锁,但在更新时会判断数据是否被更改,适用于多读场景。常见案例有java atomic原子类,底层原理的cas机制(比较并交换)就是在更新时传入预期值、目标值,仅当其值等于预期值时才会更新;数据库write_condition机制大同小异,小异指的是数据库会给记录添加version(版本),根据版本号判断当前事务是否成功。
悲观锁:取数据时总认为会被修改,固每每取数据前都会上锁,上锁之后其它线程想取数据就会被阻塞,直到它用完并解锁。像数据库的行锁、页锁、表锁、读写锁以及java synchronize关键字都可归类为悲观锁。

行锁、页锁、表锁

行锁:是mysql粒度最小的锁,只针对操作行,可大大减少锁冲突概率,并发度高,但加锁慢,开销大,会出现死锁,可分为共享锁和排它锁。
表锁:对整张表加锁,加锁快开销小,不会出现死锁,但并发度低,会增加锁冲突的概率,可分为共享锁和排它锁。
页锁:行锁与表锁的折中方案,优劣介于它们之间,1次锁定相邻的1组记录,会出现死锁,可分为共享锁和排它锁。

共享锁和排它锁

共享锁:亦称为读锁或S锁,加共享锁之后只能对数据做查询,不可增删改,可并发读取,但其它事务不能再对其加排它锁。
排它锁:可唤作写锁、X锁或独占锁,加此锁后数据只能被锁拥有者增删改查,其它事务均不可再对其加锁,直到拥有者将锁释放。

互斥锁

官方概念:在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
个人理解:类似解决CAS中ABA问题的AtomicMarkableReference、AtomicStampedReference。

死锁

多个线程出现资源竞争互相等待的情况
例子:线程1获得A的锁后等待获取B,线程2获得B的锁后等待获取A,永无止境

活锁

线程或任务没有被阻塞,由于条件不满足导致重复的尝试、失败,尝试、失败…

猜你喜欢

转载自blog.csdn.net/XingLiSir/article/details/113541386