计算机在并发的情况下很大可能会出现数据错乱的问题,因此运入了“锁”用于解决该类问题。 常见的锁:互斥锁、自旋锁、读写锁、悲观锁、乐观锁

互斥锁

特点:容易实现,最基础的锁概念

解释:在使用一个资源时,先上锁使用。上锁后其他线程都无法再上锁。直到解锁后,其他线程才能上锁使用。

生活例子:公共厕所,谁要上厕所就要先上锁后使用,避免其他人也闯入使用厕所。

自旋锁

自旋锁与互斥锁十分类似。 区别:

  • 自旋锁:加锁失败,线程还是会不断的去申请加锁,直到他拿到锁
  • 互斥锁:加锁失败,线程会释放CPU资源,等待解锁后在申请上锁。

生活例子 -> 公共厕所 自旋锁:不断的在门口敲门,直到里面的人出来 互斥锁:不动了,直到里面的人出来叫你。

读写锁

顾名思义就是由读锁写锁组成的。读数据往往是可以并发的读,并发写数据可能会导致数据不符合预期的情况

  • 读数据需要满足目前无写锁。
  • 写数据需要满足目前无写锁、读锁。 生活例子:假设一个班级的考试成绩都写到同一个本子上。而学生会读成绩,老师会写成绩。学生看成绩可以同时看,而语文老师和数学老师不能并发的把成绩写到一页里。

读写锁可以分为 读优先锁 写优先锁 公平读写锁

  • 读优先锁 学生看到有老师在等待改写数据时,不理会老师继续读数据
  • 写优先锁
    • 读数据还需要满足无在等待的写锁

      学生看到有老师在等待改写数据时,会主动让老师写数据。

  • 公平读写锁
    • 将读学请求放入一个队列,排队的去读写

      学生和老师排个队伍

乐观锁与悲观锁

互斥锁、自旋锁、读写锁都是悲观锁

悲观锁:多线程同时修改共享资源的概率比较高,容易发生冲突。因此访问共享资源前需要上锁。 乐观锁:认为发生冲突的概率比较低。并不会上任何的锁,而是校验该数据是否别修改过,修改过着放弃本次操作