本文主要介绍分布式锁的基本概念以及实现。

分布式锁

分布式锁需要满足的特性:

  • 可见性:多个线程都能看到相同的结果,注意:这个地方说的可见性并不是并发编程中指的内存可见性,只是说多个进程之间都能感知到变化的意思

  • 互斥:互斥是分布式锁的最基本的条件,使得程序串行执行

  • 高可用:程序不易崩溃,时时刻刻都保证较高的可用性

  • 高性能:由于加锁本身就让性能降低,所有对于分布式锁本身需要他就较高的加锁性能和释放锁性能

  • 安全性:安全也是程序中必不可少的一环

分布式锁的三种实现方式:

1653382219377

Redis实现分布式锁

在这里我们利用了redis单线程,所有的redis请求都会被串行化处理的特点,结合setnx命令来实现分布式锁,同时利用redis的ttl来防止死锁。

当有多个线程进入时,我们就利用该方法,第一个线程进入时,redis 中还没有这个key ,返回了1,如果结果是1,则表示他抢到了锁,那么他去执行业务,然后再删除锁,退出锁逻辑,没有抢到锁的线程,等待一定时间后重试或者直接返回即可。

在上述描述中,会出现一些问题:锁的误删原子性

分布式锁误删

1653385920025

如上图,线程1误删了线程2的锁。解决办法,在存入锁时,放入自己的标识,在删除锁时,判断当前这把锁的标识是不是自己存入的,如果是,则进行删除,如果不是,则不进行删除。

分布式锁的原子性

1653387764938

如上图,当线程1判断这把锁是自己的之后,还没来的及删除,就被阻塞住了(调度),这时锁超时释放,线程2获取到锁执行业务,但是后面又被线程1删除。

解决方式:Redis提供了Lua脚本功能,在一个脚本中编写多条Redis命令,确保多条命令执行时的原子性。

Redisson

可重入以及看门狗

MutilLock

1653553093967

上次更新:
Contributors: YangZhang