什么是分布式锁定?
多线程程序要求不同的线程访问同一资源。 但是,如果允许所有线程同时访问资源,则可能会发生冲突、错误和其他意外行为。
为了确保两个线程不同时访问同一资源,并且资源以可预测的顺序运行,程序员使用一种称为锁定的机制。 每个线程首先获取锁定,操作资源,最后将锁定释放到其他线程。
在Java中,出于许多原因,锁定对象比使用同步块更灵活。 首先,可以通过多种方式运行Lock API,但同步块完全包含在一个方法中。
此外,线程被阻止后,将无法访问同步块。 使用Lock时,线程仅在可用时获取锁定。 这大大减少了线程等待的时间。 也可以在线程等待时调用方法来中断线程。 当线程等待获取同步块时,这是不可能的。
分布式锁定意味着不仅要考虑多个线程和进程,还必须考虑在不同计算机上运行的不同客户端。 这些单独的服务必须进行协调,以确保在任何给定时间只有一个服务在使用资源。
基于Redis的分布式锁定工具
此Redisson框架是Redis的内存数据网格,为需要运行分布式锁定编程人员的用户提供了多个对象。 下面介绍每个选项及其区别。
1 .锁定
此RLock接口实现了Java.util.concurrent.locks.lock接口。 这是一个可重新输入的锁定,意味着线程可以多次锁定资源。 计数器变量记录锁定请求的次数。 当线程发出足够的解锁请求且计数器达到0时,资源将被释放。
以下简单代码示例说明如何在Redisson上创建和启动Lock。
如果获取此锁定的Redisson实例崩溃,该锁定可能会在此获取状态下永久挂起。 为了避免这种情况,Redisson会维护锁定,并在保留锁定的Redisson实例仍然存在时延长锁定的过期时间。 默认情况下,此锁定监视器的超时时间为30秒。 可以在Config.lockWatchdogTimeout设置中更改此限制。
在Redisson中,还可以指定leaseTime参数。 在指定的时间间隔后,锁定将自动解除。
2. FairLock
RFairLock也实现了Java.util.concurrent.locks.lock接口。 使用FairLock,可以确保线程按照请求的顺序获取资源。 也就是说,“先进先出”。 Redisson为队列中的下一个线程在解锁资源之前重新启动的线程提供5秒钟的重新启动时间。
同时,RLocks是一个创建FairLock很简单的过程:
3 .读写锁定
RReadWriteLock实现了Java.util.concurrent.locks.read write lock接口。 读/写锁定实际上是两个锁定的组合,一个是多个线程可以同时具有的只读锁定,另一个是一个线程只能具有的写入锁定。
创建RReadWriteLock的方法如下:
4. RedLock
此RedissonRedLock对象实现了Redlock锁定算法,使Redis可以使用分布式锁定。
在Redlock算法中,每个计算机或虚拟机都有多个独立的Redis主节点。 该算法尝试使用相同的键名和随机值按顺序获取每个实例的锁定。 只有在客户端可以比锁定有效的总时间早从大多数实例获取锁定时,才能获取锁定。