多线程并发解决方案-分布式锁

分布式锁

  • 基于Redis
    1.可以使用Redisson实现分布式锁;
 @SpringBootTest
class DemoApplicationTests {
    @Resource
    private Redisson redisson;
    @Resource
    private RedisTemplate redisTemplate;


    @Test
    public void deductStock() {
        //获取锁
        String lockKey = "lockKey";
        RLock lock = redisson.getLock(lockKey);
        lock.lock();
        //业务代码
        try{
            int stock = Integer.parseInt((String) redisTemplate.opsForValue().get("stock"));
            redisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);

            if(stock > 0){
                redisTemplate.opsForValue().set("stock",(stock-1)+"");
                System.out.println("扣减成功,库存stock:"+(stock - 1) + "");
            }else{
                System.out.println("扣减失败,库存不足");
            }
        }finally {
        	//一定要在finally块中释放锁
            lock.unlock();
        }
    }
}

Redisson原理如下,帮助理解:
在这里插入图片描述
会出现的问题:lock刚发送到master节点,还未同步到slave节点时,master节点挂掉。slave节点变为master节点,此时会导致线程可以获取到锁,但时线程仍然持有锁且正在执行业务逻辑代码。解决方案:使用zk分布式锁

  • 基于Zookeeper
    zk为什么能够解决上述出现的问题:zk的分布式集群机制和选举机制天生支持所丢失问题。watch回调机制可以优化Redisson的自旋问题。
    zk集群中,leader会先讲信息同步到follwer节点存储到log中,然后给leader节点发送ack,当leader收到半数以上的ack时,才会返回给客户端数据创建成功。如果leader节点挂了,zk集群会选出信最多的follwer节点作为leader节点,保证不会造成所丢失问题。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值