SpringBoot整合redisson实现分布式锁

通过 SpringBoot 整合 redisson 来实现分布式锁,并结合 demo 测试结果。

首先看下大佬总结的图

来源:https://www.cnblogs.com/qdhxhz/p/11046905.html

正文

增加依赖

        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot </groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.10.6</version>
        </dependency>

 

配置 信息

    spring:
      # redis
      redis:
        host: 47.103.5.190
        port: 6379
        jedis:
          pool:
            # 连接池最大连接数(使用负值表示没有限制)
            max-active: 100
            # 连接池中的最小空闲连接
            max-idle: 10
            # 连接池最大阻塞等待时间(使用负值表示没有限制)
            max-wait: -1
          # 连接超时时间(毫秒)
          timeout: 5000
          #默认是索引为0的数据库
          database: 0

 

配置类

    /**

     * redisson 配置,下面是单节点配置:

     *

     * @author gourd

     */

    @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;


        @Bean

        public RedissonClient redissonClient() {

            Config config = new Config();

            //单节点

            config.useSingleServer().setAddress("redis://" + host + ":" + port);

            if (StringUtils.isEmpty(password)) {

                config.useSingleServer().setPassword(null);

            } else {

                config.useSingleServer().setPassword(password);

            }

            //添加主从配置
    // config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});

            // 集群模式配置 setScanInterval()扫描间隔时间,单位是毫秒, //可以用"rediss://"来启用SSL连接
    // config.useClusterServers().setScanInterval(2000).addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001").addNodeAddress("redis://127.0.0.1:7002");
            return Redisson.create(config);
        }
    }

 

Redisson 工具类

    /**

     * redis分布式锁帮助类

     * @author gourd

     *

     */

    public class RedisLockUtil {


        private static DistributedLocker distributedLocker = SpringContextHolder.getBean("distributedLocker",DistributedLocker.class);


        /**

         * 加锁

         * @param lockKey

         * @return

         */

        public static RLock lock(String lockKey) {

            return distributedLocker.lock(lockKey);

        }


        /**

         * 释放锁

         * @param lockKey

         */

        public static void unlock(String lockKey) {

            distributedLocker.unlock(lockKey);

        }


        /**

         * 释放锁

         * @param lock

         */

        public static void unlock(RLock lock) {

            distributedLocker.unlock(lock);

        }


        /**

         * 带超时的锁

         * @param lockKey

         * @param timeout 超时时间   单位:秒

         */

        public static RLock lock(String lockKey, int timeout) {

            return distributedLocker.lock(lockKey, timeout);

        }


        /**

         * 带超时的锁

         * @param lockKey

         * @param unit 时间单位

         * @param timeout 超时时间

         */

        public static RLock lock(String lockKey, int timeout,TimeUnit unit ) {

            return distributedLocker.lock(lockKey, unit, timeout);

        }


        /**

         * 尝试获取锁

         * @param lockKey

         * @param waitTime 最多等待时间

         * @param leaseTime 上锁后自动释放锁时间

         * @return

         */

        public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {

            return distributedLocker.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime);

        }


        /**

         * 尝试获取锁

         * @param lockKey

         * @param unit 时间单位

         * @param waitTime 最多等待时间

         * @param leaseTime 上锁后自动释放锁时间

         * @return

         */

        public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {

            return distributedLocker.tryLock(lockKey, unit, waitTime, leaseTime);

        }


        /**

         * 获取计数器

         *

         * @param name

         * @return

         */

        public static RCountDownLatch getCountDownLatch(String name){

            return distributedLocker.getCountDownLatch(name);

        }


        /**

         * 获取信号量

         *

         * @param name

         * @return

         */

        public static RSemaphore getSemaphore(String name){

            return distributedLocker.getSemaphore(name);

        }

    }

 

底层封装

 

    /**

     * @author gourd

     */

    public interface DistributedLocker {


        RLock lock(String lockKey);


        RLock lock(String lockKey, int timeout);


        RLock lock(String lockKey, TimeUnit unit, int timeout);


        boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);


        void unlock(String lockKey);


        void unlock(RLock lock);

    }


    /**

     * @author gourd

     */

    @Component

    public class RedisDistributedLocker implements DistributedLocker {


        @Autowired

        private RedissonClient redissonClient;


        @Override

        public RLock lock(String lockKey) {

            RLock lock = redissonClient.getLock(lockKey);

            lock.lock();

            return lock;

        }


        @Override

        public RLock lock(String lockKey, int leaseTime) {

            RLock lock = redissonClient.getLock(lockKey);

            lock.lock(leaseTime, TimeUnit.SECONDS);

            return lock;

        }


        @Override

        public RLock lock(String lockKey, TimeUnit unit ,int timeout) {

            RLock lock = redissonClient.getLock(lockKey);

            lock.lock(timeout, unit);

            return lock;

        }


        @Override

        public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {

            RLock lock = redissonClient.getLock(lockKey);

            try {

                return lock.tryLock(waitTime, leaseTime, unit);

            } catch (InterruptedException e) {

                return false;

            }

        }


        @Override

        public void unlock(String lockKey) {

            RLock lock = redissonClient.getLock(lockKey);

            lock.unlock();

        }


        @Override

        public void unlock(RLock lock) {

            lock.unlock();

        }

    }

测试

模拟并发测试

    /**

     * redis分布式锁控制器

     * @author gourd

     * @since 2019-07-30

     */

    @RestController

    @Api(tags = "redisson", description = "redis分布式锁控制器" )

    @RequestMapping("/redisson" )

    @Slf4j

    public class RedissonLockController {


        /**

         * 锁测试共享变量

         */

        private Integer lockCount = 10;


        /**

         * 无锁测试共享变量

         */

        private Integer count = 10;


        /**

         * 模拟线程数

         */

        private static int threadNum = 10;


        /**

         * 模拟并发测试加锁和不加锁

         * @return

         */

        @GetMapping("/test")

        @ApiOperation(value = "模拟并发测试加锁和不加锁")

        public void lock(){

            // 计数器

            final CountDownLatch countDownLatch = new CountDownLatch(1);

            for (int i = 0; i < threadNum; i ++) {

                MyRunnable myRunnable = new MyRunnable(countDownLatch);

                Thread myThread = new Thread(myRunnable);

                myThread.start();

            }

            // 释放所有线程

            countDownLatch.countDown();

        }


        /**

         * 加锁测试

         */

        private void testLockCount() {

            String lockKey = "lock-test";

            try {

                // 加锁,设置超时时间2s

                RedisLockUtil.lock(lockKey,2, TimeUnit.SECONDS);

                lockCount--;

                log.info("lockCount值:"+lockCount);

            }catch (Exception e){

                log.error(e.getMessage(),e);

            }finally {

                // 释放锁

                RedisLockUtil.unlock(lockKey);

            }

        }


        /**

         * 无锁测试

         */

        private void testCount() {

            count--;

            log.info("count值:"+count);

        }



        public class MyRunnable implements Runnable {

            /**

             * 计数器

             */

            final CountDownLatch countDownLatch;


            public MyRunnable(CountDownLatch countDownLatch) {

                this.countDownLatch = countDownLatch;

            }


            @Override

            public void run() {

                try {

                    // 阻塞当前线程,直到计时器的值为0

                    countDownLatch.await();

                } catch (InterruptedException e) {

                    log.error(e.getMessage(),e);

                }

                // 无锁操作

                testCount();

                // 加锁操作

                testLockCount();

            }


        }


    }

 

调用接口后打印值:

 测试结果

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值