利用Redis实现分布式锁

本文介绍了利用Redis实现分布式锁的原理和方法,包括线程锁的概念、分布式锁的必要性和实现方式,通过示例代码展示了如何使用Redis的SETNX命令创建分布式锁,以及在Node.js中实现的redlock。最后,结合实际项目中遇到的问题,阐述了分布式锁如何解决并发场景下的数据一致性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用Redis实现分布式锁

在之前的答题对战项目中,游戏规则是根据双方回答同一道题所花时间长短判胜负,但测试过程中遇到一个偶现BUG:“对战开始后双方收到的题目不一致”,经过分析代码,发现问题原因在于发题逻辑没有加锁,所以写篇文章聊聊这个话题。

什么是锁

在编程领域,锁是一种用来做独占代码执行的方式,通俗来讲就是在打算做某件事情之前要申请许可证,如果没有得到许可证则无法做这件事。需要许可证的原因是因为并发现象:“同时出现多个人做这件事”,这种并发现象可能导致逻辑错误。在许可证这个比喻中,“人”是计算机领域的线程、进程等,要做的“事情”则是执行代码。

线程锁

假设有这样一段Java代码:

class Account {
    private int money;

    Account(int init) {
        this.money = init;
    }

    // 购买一个价格为price的商品,成功返回true,否则返回false
    public boolean buyWithPrice(int price) {
        if (this.money < price) {
            return false;
        }

        this.money -= price;
        return true;
    }

    public static void main(String[] args) {
        Account account = new Account(100); 

        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (account.buyWithPrice(100)) {
                        System.out.println("buy success");
                    }
                }
            }).start();
        }
    }
}

因为Javascript是单线程模型,不方便直接模拟线程并发,所以这一段示例代码用的是Java语言。示例中模拟了一个最简单的账户购物场景:“用账户余额(money)购买指定价格(price)的商品,购买成功返回true,余额不够则返回false”,场景中初始化一个余额为100的账户,然后创建两个线程去执行购买操作。

上述场景期望的正确结果是只有一个线程购买成功,另外一个会由于余额不足购买失败,所以我们执行代码只会打印一行'buy success'。但实际运行结果却可能与我们所期望的不同,出现两个线程都购买成功,而出现两者都成功的原因是因为buyWithPrice方法没有“加锁”(Java中称为非线程同步方法),在并发情况下,线程双方在this.money -= price没有执行之前,都执行到if (this.money < price)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值