1、导入maven坐标
   
    - 
     
      
     
     
      
       <!-- 用redisson作为所有分布式锁,分布式对象等功能框架-->
      
     
- 
     
      
     
     
      
           <dependency>
      
     
- 
     
      
     
     
      
               <groupId>org.redisson</groupId>
      
     
- 
     
      
     
     
      
               <artifactId>redisson</artifactId>
      
     
- 
     
      
     
     
      
               <version>
       3.12
       .5</version>
      
     
- 
     
      
     
     
      
           </dependency>
      
     
2、redisson配置类(如果redis没有密码就不需要private String password)
   
    - 
     
      
     
     
      
       package com.xuechengpluscommon.config;
      
     
- 
     
      
     
     
       
      
     
- 
     
      
     
     
      
       import org.redisson.Redisson;
      
     
- 
     
      
     
     
      
       import org.redisson.api.RedissonClient;
      
     
- 
     
      
     
     
      
       import org.redisson.config.Config;
      
     
- 
     
      
     
     
      
       import org.redisson.config.SingleServerConfig;
      
     
- 
     
      
     
     
      
       import org.springframework.beans.factory.annotation.Value;
      
     
- 
     
      
     
     
      
       import org.springframework.context.annotation.Bean;
      
     
- 
     
      
     
     
      
       import org.springframework.context.annotation.Configuration;
      
     
- 
     
      
     
     
       
      
     
- 
     
      
     
     
      
       /**
      
     
- 
     
      
     
     
      
        * @description Redisson 配置类
      
     
- 
     
      
     
     
      
        */
      
     
- 
     
      
     
     
      
       @Configuration
      
     
- 
     
      
     
     
      
       public 
       class 
       MyRedissonConfig {
      
     
- 
     
      
     
     
       
      
     
- 
     
      
     
     
          
       @Value(value = "${spring.redis.host}")
      
     
- 
     
      
     
     
          
       private String host;
      
     
- 
     
      
     
     
          
       @Value(value = "${spring.redis.port}")
      
     
- 
     
      
     
     
          
       private 
       int port;
      
     
- 
     
      
     
     
          
       @Value(value = "${spring.redis.database}")
      
     
- 
     
      
     
     
          
       private 
       int database;
      
     
- 
     
      
     
     
      
       // @Value(value = "${spring.redis.password}")
      
     
- 
     
      
     
     
      
       // private String password;
      
     
- 
     
      
     
     
       
      
     
- 
     
      
     
     
          
       /**
      
     
- 
     
      
     
     
      
        * 单Redis节点模式配置方法
      
     
- 
     
      
     
     
      
        * 其他配置參數,看:
      
     
- 
     
      
     
     
      
        * <a href = "https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95#26-%E5%8D%95redis%E8%8A%82%E7%82%B9%E6%A8%A1%E5%BC%8F">
      
     
- 
     
      
     
     
      
        * 单Redis节点模式配置方法
      
     
- 
     
      
     
     
      
        * </a>
      
     
- 
     
      
     
     
      
        *
      
     
- 
     
      
     
     
      
        * @return {@link RedissonClient}
      
     
- 
     
      
     
     
      
        */
      
     
- 
     
      
     
     
          
       @Bean(destroyMethod = "shutdown")
      
     
- 
     
      
     
     
      
           RedissonClient 
       redisson
       () {
      
     
- 
     
      
     
     
              
       Config 
       config 
       = 
       new 
       Config();
      
     
- 
     
      
     
     
              
       //Redis多节点
      
     
- 
     
      
     
     
              
       // config.useClusterServers()
      
     
- 
     
      
     
     
              
       // .addNodeAddress("redis://127.0.0.1:6379", "redis://127.0.0.1:7001");
      
     
- 
     
      
     
     
              
       //Redis单节点
      
     
- 
     
      
     
     
              
       SingleServerConfig 
       singleServerConfig 
       = config.useSingleServer();
      
     
- 
     
      
     
     
              
       //可以用"rediss://"来启用SSL连接
      
     
- 
     
      
     
     
              
       String 
       address 
       = 
       "redis://" + host + 
       ":" + port;
      
     
- 
     
      
     
     
      
               singleServerConfig.setAddress(address);
      
     
- 
     
      
     
     
              
       //设置 数据库编号
      
     
- 
     
      
     
     
      
               singleServerConfig.setDatabase(database);
      
     
- 
     
      
     
     
      
       // singleServerConfig.setPassword(password);
      
     
- 
     
      
     
     
              
       //连接池大小:默认值:64
      
     
- 
     
      
     
     
              
       // singleServerConfig.setConnectionPoolSize()
      
     
- 
     
      
     
     
              
       return Redisson.create(config);
      
     
- 
     
      
     
     
      
           }
      
     
- 
     
      
     
     
       
      
     
- 
     
      
     
     
      
       }
      
     
  yml中redis的配置
   
    - 
     
      
     
     
      
       redis:
      
     
- 
     
      
     
     
      
           database: 
       0
      
     
- 
     
      
     
     
      
           host: ip地址
      
     
- 
     
      
     
     
      
           port: 
       6379
      
     
3、创建redisson的bean
   
    - 
     
      
     
     
      
       @Autowired
      
     
- 
     
      
     
     
      
       private RedissonClient redisson;
      
     
4、测试,入队
   
    - 
     
      
     
     
      
       @Test
      
     
- 
     
      
     
     
      
       void 
       contextLoads1
       () {
      
     
- 
     
      
     
     
      
           RQueue<String> queue = redisson.getQueue(
       "RedissonQueue");
      
     
- 
     
      
     
     
      
           queue.add(
       "hello");
      
     
- 
     
      
     
     
      
           System.out.println(queue);
      
     
- 
     
      
     
     
      
       }
      
     
redis数据
 
 
   5、测试,出队
   
    - 
     
      
     
     
      
       @Test
      
     
- 
     
      
     
     
      
       void 
       contextLoads2
       () {
      
     
- 
     
      
     
     
      
           RQueue<String> queue = redisson.getQueue(
       "RedissonQueue");
      
     
- 
     
      
     
     
          
       String 
       remove 
       = queue.remove();
      
     
- 
     
      
     
     
      
           System.out.println(remove);
      
     
- 
     
      
     
     
      
       }
      
     
出队数据:
 
 
   6、分布式锁
   
    - 
     
      
     
     
      
       public R 
       redisTest1
       () 
       throws InterruptedException {
      
     
- 
     
      
     
     
              
       //首先从redis查询数据
      
     
- 
     
      
     
     
      
               Orders redisOrder;
      
     
- 
     
      
     
     
      
               redisOrder=(Orders) redisTemplate.opsForValue().get(
       "redisTest");
      
     
- 
     
      
     
     
              
       //如果存在redis则返回
      
     
- 
     
      
     
     
              
       if(ObjectUtils.isNotEmpty(redisOrder)){
      
     
- 
     
      
     
     
                  
       return R.ok(redisOrder);
      
     
- 
     
      
     
     
                  
       //如果不存在则从数据库查询
      
     
- 
     
      
     
     
      
               }
       else {
      
     
- 
     
      
     
     
                  
       //首先获取分布式锁
      
     
- 
     
      
     
     
                  
       RLock 
       lock 
       = redissonClient.getLock(
       "redisTestDogWatch");
      
     
- 
     
      
     
     
                  
       //上锁
      
     
- 
     
      
     
     
      
                   lock.lock();
      
     
- 
     
      
     
     
       
      
     
- 
     
      
     
     
                  
       //获取锁之后进行查询
      
     
- 
     
      
     
     
                  
       try {
      
     
- 
     
      
     
     
      
                       redisOrder = (Orders) redisTemplate.opsForValue().get(
       "redisTest");
      
     
- 
     
      
     
     
                      
       if (ObjectUtils.isNotEmpty(redisOrder)) {
      
     
- 
     
      
     
     
                          
       return R.ok(redisOrder);
      
     
- 
     
      
     
     
      
                       }
      
     
- 
     
      
     
     
                      
       //数据库查询
      
     
- 
     
      
     
     
      
                       redisOrder= ordersService.getById(
       1577177773194113014L);
      
     
- 
     
      
     
     
      
                       redisTemplate.opsForValue().set(
       "redisTest", redisOrder );
      
     
- 
     
      
     
     
      
                       System.out.println(
       "[从数据库中查询]");
      
     
- 
     
      
     
     
       
      
     
- 
     
      
     
     
      
                   } 
       catch (Exception e) {
      
     
- 
     
      
     
     
      
                       e.printStackTrace();
      
     
- 
     
      
     
     
      
                   } 
       finally {
      
     
- 
     
      
     
     
                      
       //删除锁
      
     
- 
     
      
     
     
      
                       lock.unlock();
      
     
- 
     
      
     
     
      
                   }
      
     
- 
     
      
     
     
                  
       return R.ok(redisOrder);
      
     
- 
     
      
     
     
      
               }
      
     
- 
     
      
     
     
      
           }
      
     
  在这里让线程睡眠35秒
   
    - 
     
      
     
     
      
       //上锁
      
     
- 
     
      
     
     
      
       lock.lock();
      
     
- 
     
      
     
     
      
       Thread.sleep(
       35000);
      
     
此时三个服务器运行
 
 
   测试结果
可以首先看到已经上锁的redisTestDogWatch,每个锁30秒,如果线程未完成则会自动续30秒,如果线程完成到finally中的unlock就删除锁
 
 
   目前可以看到只有一个服务器获取到锁
 
 
   存储redis的数据
 
 
   此时进行并发测试
 
 
   依旧保持35秒的睡眠时间
此时可以看到未拿到锁的线程报错
java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: d904f2b9-e75d-472d-a5a6-d0a8cc603a80 thread-id: 210尝试解锁锁定,未被当前线程锁定 按节点 ID:C731FAC4-9BF7-4F4A-ACC1-A2CC9B78A02F 线程 ID:232
这是因为锁住了,所以无法获取锁,然后看门狗会不断刷新
 
 
   转载:https://blog.csdn.net/weixin_55127182/article/details/129125249
查看评论
					 
					