各种锁的概念

Posted qwertilh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种锁的概念相关的知识,希望对你有一定的参考价值。

0、前言

JAVA 亦或是 OS 中会出现非常之多不同的锁,这些锁大多都按特性、功能、设计、属性等作为依据来进行分类,而不是具体到某一种代码实现

 

1、公平锁 vs 非公平锁

概念:在并发环境中,线程在获得锁的顺序/优先级是根据申请的时间顺序来安排的(FIFO),这样保证了所有的线程都有机会得到锁,不会产生操作系统概念中 “饥饿” 情况的产生,这样的锁机制称为公平锁。相反,如果在获得锁的过程中,先申请锁的线程有可能被后申请的锁抢占的情况则为非公平锁。

 

JAVA例子:JAVA 中 ReentrantLock 就可以分别实现公平和非公平两种方式。源码解析

 

2、可重入锁(递归锁) vs 不可重入锁(自旋锁)

概念:可重入锁指的是线程获得了某种锁(不妨称为 A 锁)且在其执行的过程中需要重复获得 A 锁,那么这个线程可依旧进入被 A 锁锁住的代码段。而不可重入锁则正好相反,一个线程不能够多次重复地进入一种锁。(如果你了解递归,那么可重入锁被也称递归锁从概念上看是十分好理解的)

 

代码示例:

下面的例子中,执行 methodA 需要获得两次 A 锁,如果 A 锁是可重入锁那么 methodB 就可以得以执行,否则(即A锁是不可重入锁)那么执行到 methodB 段就会被阻塞,需要 A锁 被执行 unlock 操作之后才能继续执行下去

技术图片
public class Demo {
  private Lock lockA;
 
  public Demo(Lock Lock) {
    this.lockA = lock;
  }
 
  public void methodA() {
    lockA.lock();
    methodB(); // 进入 B 后需要重复获得 lockA 锁
    lockA.unlock();
  }
 
  public void methodB() {
    lockA.lock();
    //dosm
    lockA.unlock();
  }
  }
View Code

使用 JAVA 代码实现简单的自旋锁(CAS)

技术图片
public class SpinLock {

  private AtomicReference<Thread> sign =new AtomicReference<>();

  public void lock(){
    Thread current = Thread.currentThread();
    while(!sign .compareAndSet(null, current)){
    }
  }

  public void unlock (){
    Thread current = Thread.currentThread();
    sign .compareAndSet(current, null);
  }
}
CAS自旋锁

CAS方式实现的乐观自旋锁能够让线程一直处于活跃状态,不会被挂起,减少了上下文切换,提高效率。

 

JAVA例子:JAVA 中 ReentrantLock 和 Synchronized 都是可重入锁

 

3、悲观锁 vs 乐观锁

概念:

悲观锁 => 有一个“悲观”的心态,既每次取数据的时候,都会认为该数据会被修改,所以必须加一把锁才安心。

乐观锁 => 乐观的孩子,认为同一个数据不会发生并发操作的行为,所以取的时候不会加锁,只有在更新的时候,会通过例如版本号之类的来判断是否数据被修改了。

 

JAVA例子:JAVA中的乐观锁基本是用 CAS 思想实现,例如 AtomicInteger

 

4、共享锁 vs 排他锁 (数据库事务)

概念:

共享锁 => 也称读锁或S锁。如果事务对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排它锁。获准共享锁的事务只能读数据,不能修改数据。

排它锁 => 也称独占锁、写锁或X锁。如果事务对数据A加上排它锁后,则其他事务不能再对A加任何类型的锁。获得排它锁的事务即能读数据又能修改数据。

 

JAVA例子:ReetrantReadWriteLock()

 

5、分布式锁

概念:我们上面聊的这些锁,都是在单个程序上面的不同线程之间来实现的,那么当我们的不同程序需要去竞争同一块资源的时候,这就需要分布式锁了,我们可以通过redis、zookeeper等中间件来实现分布式锁。

 

6、偏向锁、轻量级锁、重量级锁

//TODO

 

 

---------------------------------------------

引用内容:link1link2

---------------------------------------------

以上是关于各种锁的概念的主要内容,如果未能解决你的问题,请参考以下文章

Redis实现分布式锁(设计模式应用实战)

Redis实现分布式锁(设计模式应用实战)

为啥基于锁的程序不能组成正确的线程安全片段?

数据库锁解析

锁的相关概念介绍

各种SQL加锁