计算机在并发的情况下很大可能会出现数据错乱的问题,因此运入了“锁”用于解决该类问题。 常见的锁:互斥锁、自旋锁、读写锁、悲观锁、乐观锁
互斥锁
特点:容易实现,最基础的锁概念
解释:在使用一个资源时,先上锁使用。上锁后其他线程都无法再上锁。直到解锁后,其他线程才能上锁使用。
生活例子:公共厕所,谁要上厕所就要先上锁后使用,避免其他人也闯入使用厕所。
自旋锁
自旋锁与互斥锁十分类似。 区别:
- 自旋锁:加锁失败,线程还是会不断的去申请加锁,直到他拿到锁
- 互斥锁:加锁失败,线程会释放CPU资源,等待解锁后在申请上锁。
生活例子 -> 公共厕所 自旋锁:不断的在门口敲门,直到里面的人出来 互斥锁:不动了,直到里面的人出来叫你。
读写锁
顾名思义就是由读锁和写锁组成的。读数据往往是可以并发的读,并发写数据可能会导致数据不符合预期的情况
- 读数据需要满足目前无写锁。
- 写数据需要满足目前无写锁、读锁。 生活例子:假设一个班级的考试成绩都写到同一个本子上。而学生会读成绩,老师会写成绩。学生看成绩可以同时看,而语文老师和数学老师不能并发的把成绩写到一页里。
读写锁可以分为 读优先锁 写优先锁 公平读写锁
- 读优先锁 学生看到有老师在等待改写数据时,不理会老师继续读数据
- 写优先锁
-
读数据还需要满足无在等待的写锁
学生看到有老师在等待改写数据时,会主动让老师写数据。
-
- 公平读写锁
-
将读学请求放入一个队列,排队的去读写
学生和老师排个队伍
-
乐观锁与悲观锁
互斥锁、自旋锁、读写锁都是悲观锁
悲观锁:多线程同时修改共享资源的概率比较高,容易发生冲突。因此访问共享资源前需要上锁。 乐观锁:认为发生冲突的概率比较低。并不会上任何的锁,而是校验该数据是否别修改过,修改过着放弃本次操作