学习一下分布式锁 尝试手写 基于lettuce

本文介绍了如何使用Lettuce实现分布式锁,对比了jedis与Lettuce的区别,强调了Lettuce的线程安全性和高性能。分布式锁的原理通过原子操作确保安全性,并指出在多线程环境下可能存在的问题。通过代码示例展示了加锁和解锁的逻辑,并通过测试证明了加锁后的累加操作是线程安全的。文章还提及了一个优化版本并提供了详细链接。
摘要由CSDN通过智能技术生成

1.redis客户端 jedis和lettuce
网上大部分是基于jedis的分布式锁 jedis是多线程下不是线程安全的 lettuce是基于netty线程安全性能高,
springboot2.0都采用lettuce,所以分布式锁最好基于lettuce
2.分布式锁原理
采用原子操作如下:
如果不存在key就设置这个key 存在这个key就阻塞住等待锁key自动或手动释放
3.多线程或多进程下存在多问题
当同步代码块阻塞时间过长,导致代码还没执行完,但是此时超过了持有锁的超时时间(key的过期时间)锁会自动被释放,之后同步代码块执行完毕后又会去执行释放锁的操作(类似unlock)。在锁超时之后,未手动释放锁之前如果其他进程重新设了一把锁,当前进程之后的手动释放又会把其他进程设置的新锁释放掉,所以在手动释放锁之前一定要核对value的值是否和设置锁的时候一致的,这样就不会把其他进程的锁给释放掉。
置key时 value一定要随机而且唯一(就像uuid)原因如上;

4.贴代码

@Component
@Slf4j
public class RedisLock {
   
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 存储当前线程  设置锁对应的value   用来释放锁时进行校验
     */
    private final ThreadLocal<String> lockValue = new ThreadLocal<>();

    private final String keyLock = "lock";


    /**
     * 获取锁 (带超时时间)
     *
     * @param timeout
     * @param expireTime
     * @return
     * @throws InterruptedException
     */
    public boolean tryLockWithTimeout(Integer timeout, Integer expireTime) {
   
        String value = UUID.randomUUID().toString();
        //获取未来过期时间点
        long invalidTime = System.currentTimeMillis() + timeout * 1000;
        boolean flag = false;
        while (System.currentTimeMillis() < invalidTime) {
   
            flag = tryLock(keyLock, value, expireTime);
            if (flag) {
   
                break;
            } else {
   
                try {
   
                    Thread.sleep(10);
                } catch (InterruptedException e) {
   
                    log.error(e.toString());
                }
            }

        }
        if (false == flag) {
   
            log.error("竞争锁失败");
        }
        return flag;
    }

    /**
     * 获取锁 (一直抢到为止) 阻塞锁
     *
     * @param expireTime 锁失效时间
     * @return
     */
    public boolean blockLock(Long expireTime) throws InterruptedException {
   
        String value = UUID.randomUUID(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值