Redis实现分布式锁

一、实现原理

使用redis里字符类型:SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]

  • EX seconds 设置指定的到期时间(以秒为单位)。
  • PX milliseconds 设置指定的到期时间(以毫秒为单位)。
  • NX 仅在键不存在时设置键。
  • XX 只有在键已存在时才设置。

二、Python实现分布式锁

# redis实现分布式锁

import time
import threading

import redis


class RedisLock:
    def __init__(self):
        self.redis_client = redis.StrictRedis(host="localhost", port=6379, db=0)
        self._lockid = None

    def get_lock(self, name, timeout):
        """
        加锁
        :param name: 锁名
        :param timeout: 超时时间
        :return: 加锁成功返回True; 加锁失败返回False
        """
        query_val = self.redis_client.get(name)
        if query_val:
            return False
        self._lockid = int(time.time() * 1000)
        lock_val = f"lock_{self._lockid}"
        set_result = self.redis_client.set(name=name, value=lock_val, ex=timeout, nx=True)
        return set_result

    def release_lock(self, name):
        """
        释放锁
        :param name: 锁名
        :return: 释放成功返回True; 释放失败返回False
        """
        query_val = self.redis_client.get(name)
        if not query_val:
            return True
        if query_val.decode("utf-8") == f"lock_{self._lockid}":
            del_nb = self.redis_client.delete(name)     # 获取到的是删除的条数
            return del_nb > 0
        return False


# ######################################## 多个线程去竞争锁
def run_task(rds_obj, lockname, timeout):
    lock_status = rds_obj.get_lock(lockname, timeout)
    print(f"rds_obj--{id(rds_obj)}: current lock status is {lock_status}")

rds_list = []
for i in range(1, 4):
    rds_obj = RedisLock()
    rds_list.append(rds_obj)
    timeout = i * 5
    lock_name = "mylock"
    td = threading.Thread(target=run_task, args=(rds_obj, lock_name, timeout))
    td.start()
    td.join()

''' 
结果输出:
rds_obj--2573431598928: current lock status is True     # 第一个线程获取锁成功
rds_obj--2573430176272: current lock status is False    # 第二、三个线程获取锁失败
rds_obj--2573470176656: current lock status is False
'''


# ######################################## 倒序逐个去释放锁
while rds_list:
    rds_obj_pop = rds_list.pop()
    release_status = rds_obj_pop.release_lock("mylock")
    print(f"rds_obj--{id(rds_obj_pop)}: release lock status is {release_status}")

'''
结果输出:
rds_obj--2573470176656: release lock status is False    # 第三、二个线程释放锁失败
rds_obj--2573430176272: release lock status is False
rds_obj--2573431598928: release lock status is True     # 第一个线程释放锁成功
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值