评论
1
分享

【数据存储】【Redis】高并发下实现分布式锁

这个是认证

我是廖志伟

2021-08-08 21:58

60256 0 1


大部分互联网公司实现分布式锁原理


    /**

     * 分布式锁底层实现原理

     * @return

     */

    @GetMapping("distributedLock")

    public Object distributedLock(){

        String lockKey = "distributedLockKey";

        //给每个线程都设置一个唯一标识,避免出现程序执行的时间超过设置的过期时间,导致其他线程删除了自己的锁

        String clientId = UUID.randomUUID().toString();

        try {

            //添加过期时间保证线程运行到一半的时候,程序崩了,导致缓存中的key一直存在

            Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

            if (!result) {

                return "error_code";

            }

            // Todo 实现业务逻辑

            redisTemplate.opsForValue().set(TestConstant.KEY_TEST,String.valueOf(System.currentTimeMillis()));

        } finally {

            //判断是不是自己的线程删除自己的锁

            if (clientId.equals(redisTemplate.opsForValue().get(lockKey))) {

                redisTemplate.delete(lockKey);

            }

        }

        //Todo 当前代码未实现锁续命功能,锁续命功能:由于程序执行时间可能超过设置缓存中锁的过期时间,导致后续一部分业务未执行,一直被其他线程抢占,需要对锁进行续命,但是由于续命的时间不好确定,这个时候就需要单独开启子线程,定时任务不断的去判断当前锁,还在不在,如果不在了,说明业务已经执行完成了,如果还在,重新设置过期时间,一般而言,定时任务的时间为缓存设置的过期时间三分之一就可以了。

        return "end";

    }


基于redisson实现高并发分布式锁

引入依赖:


        <dependency>

            <groupId>org.redisson</groupId>

            <artifactId>redisson</artifactId>

            <version>3.6.5</version>

        </dependency>


启动类中注入bean对象:


    @Bean

    public Redisson redisson() {

        // 此为单机模式

        Config config = new Config();

        config.useSingleServer().setAddress("redis://localhost:6379").setDatabase(0);

        return (Redisson) Redisson.create(config);

    }


实现分布式:

    @Autowired

    RedisTemplate redisTemplate;


    @Autowired

    private Redisson redisson;


    /**

     * 基于redisson实现高并发分布式锁

     * @return

     */

    @GetMapping("highConcurrencyDistributedLock")

    public Object highConcurrencyDistributedLock(){

        RLock redissonLock = redisson.getLock(TestConstant.HIGH_CONCURRENCY_DISTRIBUTED_LOCK);

        try {

            //加锁,实现了key设置,过期时间,锁续命功能

            redissonLock.lock();  //redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

            // Todo 实现业务逻辑

            redisTemplate.opsForValue().set(TestConstant.KEY_TEST,String.valueOf(System.currentTimeMillis()));

        } finally {

            //释放锁

            redissonLock.unlock();

        }

        return redisTemplate.opsForValue().get(TestConstant.KEY_TEST);

    }


本文为凯迪网自媒体“凯迪号”作者上传发布,代表其个人观点与立场,凯迪网仅提供信息发布与储存服务。文章内容之真实性、准确性由用户自行辨别,凯迪网有权利对涉嫌违反相关法律、法规内容进行相应处置。
举报
投喂支持
1人点赞
发表评论
请先 注册 / 登录后参与评论
推荐阅读