• Redisson实现分布式锁


    1、Redisson简介

    Redis 是最流行的 NoSQL 数据库解决方案之一,而 Java 是世界上最流行(注意,没有说“最好”)的编程语言之一。虽然两者看起来很自然地在一起“工作”,但是要知道,Redis 其实并没有对 Java 提供原生支持。

    相反,作为 Java 开发人员,我们若想在程序中集成 Redis,必须使用 Redis 的第三方库。而 Redisson 就是用于在 Java 程序中操作 Redis 的库,它使得我们可以在程序中轻松地使用 Redis。Redisson 在 java.util 中常用接口的基础上,为我们提供了一系列具有分布式特性的工具类。

    Redisson底层采用的是Netty 框架。支持Redis 2.8以上版本,支持Java1.6+以上版本。

    2、Redisson实现分布式锁的步骤

    **2.1.**引入依赖

    引入重要的两个依赖,一个是spring-boot-starter-data-redis,一个是redisson:

    
    
        org.projectlombok
        lombok
    
    
    
        org.springframework.boot
        spring-boot-starter-data-redis
    
    
        org.redisson
        redisson
        3.7.5
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.2.application.properties

    # Redis服务器地址
    spring.redis.host=192.168.3.28
    # Redis服务器连接密码(默认为空)
    spring.redis.password=
    # Redis服务器连接端口
    spring.redis.port=6379
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3.Redisson的配置类

    创建一个redisson的配置类RedissonConfig,内容如下:

    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.io.IOException;
    
    @Configuration
    public class RedissonConfig {
    
        @Value("${spring.redis.host}")
        private String host;
    
        @Value("${spring.redis.port}")
        private String port;
    
        //@Value("${spring.redis.password}")
        //private String password;
    
        /**
         * RedissonClient,单机模式
         * @return
         * @throws IOException
         */
        @Bean(destroyMethod = "shutdown")
        public RedissonClient redisson() throws IOException {
            Config config = new Config();
            //config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password);
            config.useSingleServer().setAddress("redis://" + host + ":" + port);
            return Redisson.create(config);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    2.4.Redisson分布式锁业务类

    import lombok.extern.slf4j.Slf4j;
    import org.redisson.api.RLock;
    import org.redisson.api.RedissonClient;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.util.concurrent.TimeUnit;
    
    @Slf4j
    @Service
    public class SkillService {
        @Resource
        RedissonClient redissonClient;
    
        private final static String LOCK_KEY = "RESOURCE_KEY";
        int n = 500;
    
        public void seckill() {
            //定义锁
            RLock lock = redissonClient.getLock(LOCK_KEY);
            //lock.lock();
            try {
                //尝试加锁,最大等待时间300毫秒,上锁30毫秒自动解锁
                if (lock.tryLock(300, 30, TimeUnit.MILLISECONDS)) {
                    log.info("线程:" + Thread.currentThread().getName() + "获得了锁");
                    log.info("剩余数量:{}", --n);
                }
            } catch (Exception e) {
                log.error("程序执行异常:{}", e);
            } finally {
                log.info("线程:" + Thread.currentThread().getName() + "准备释放锁");
                //释放锁
                lock.unlock();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    2.5.Redisson分布式锁测试

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class SkillServiceTest {
    
        @Autowired
        SkillService service;
    
        @RequestMapping("/testSkillService")
        public void TestSkillService(){
            for (int i = 10; i < 60; i++) { //开50个线程
                SkillThread skillThread = new SkillThread(service, "skillThread->" + i);
                skillThread.start();
            }
        }
    }
    
    class SkillThread extends Thread {
    
        private SkillService skillService;
    
        public SkillThread(SkillService skillService, String skillThreadName) {
            super(skillThreadName);
            this.skillService = skillService;
        }
    
        @Override
        public void run() {
            skillService.seckill();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    测试结果如下:

    全部都是按照顺序依次执行。

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    简洁易用,更多算法,快来开箱新一代视频目标感知开源工具箱
    CSS3基础:字体和文本调整
    强烈推荐十几款IDEA开发必备的插件
    【HTML5】调查问卷制作简约版
    Clickhouse备份恢复_clickhouse-client方式backup命令之备份目录的设置
    Elasticsearch 深入理解search After 处理深度分页问题
    python的数据类型转换以及运算符
    聚焦“教-学-评-测-练-管一体化”,推动新型人才培养
    设计模式-day02
    深度学习推荐系统(八)AFM模型及其在Criteo数据集上的应用
  • 原文地址:https://blog.csdn.net/m0_52789121/article/details/126113990