redis锁

时间:2023-12-04 14:26:11

1.引入依赖:

 <!--使用redis客户端需要用到的包  -->
         <dependency>
               <groupId>redis.clients</groupId>
               <artifactId>jedis</artifactId>
               <version>2.9.0</version>
         </dependency>
         <dependency>
              <groupId>org.apache.commons</groupId>
              <artifactId>commons-pool2</artifactId>
              <version>2.4.3</version>
          </dependency>

2.连接redis:

 package com.karat.cn.redis;

 import redis.clients.jedis.Jedis;
 import redis.clients.jedis.JedisPool;
 import redis.clients.jedis.JedisPoolConfig;
 /**
  * 客户端连接redis
  * @author 开发
  *
  */
 public class RedisManager {

     private static JedisPool jedisPool;

     static {
         JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
         jedisPoolConfig.setMaxTotal(20);//最大连接数, 默认8个
         jedisPoolConfig.setMaxIdle(10);//最小空闲连接数, 默认0
         jedisPool=new JedisPool(jedisPoolConfig, "47.107.121.215",6379);
     }

     public static Jedis getJedis() throws Exception {
         if(jedisPool!=null) {
             //getResource()方法从连接池中取得一个Jedis实例
             return jedisPool.getResource();
         }
         throw new Exception("jedis启动异常");
     }
 }

3.锁测试:

 package com.karat.cn.redis;

 import java.util.List;
 import java.util.UUID;

 import redis.clients.jedis.Jedis;
 import redis.clients.jedis.Transaction;

 public class RedisLock {
     /**
      * 上锁
      * @param key    锁key值
      * @param timeout    获取请求时间(多长时间获取不到锁表示失败)
      * @return
      */
     public String getLock(String key,int timeout) {
         try {
             Jedis jedis=RedisManager.getJedis();//连接获取jedis实列

             String value=UUID.randomUUID().toString();//随机设置值UUID(值无所谓)

             //连接超时时间,到了该设置时间,锁还没有被释放(没有抢到),结束
             long end=System.currentTimeMillis()+timeout;

             while(System.currentTimeMillis()<end) {//阻塞
                 /**
                  * setnx
                  * 返回整数,具体为
                  * 1,当 key 的值被设置
                  * 0,当 key 的值没被设置
                  */
                 if(jedis.setnx(key, value)==1) {//插入数据成功
                     //设置key超时时间
                     jedis.expire(key, timeout);
                     //锁设置成功,redis操作成功
                     return value;
                 }
                 //获得key的过期时间
                 if(jedis.ttl(key)==1){
                     jedis.expire(key, timeout);
                 }

                 Thread.sleep(1000);
             }
         } catch (Exception e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return null;
     }
     /**
      * 释放锁
      * @param key
      * @param value
      * @return
      */
     public boolean delLock(String key,String value) {
         try {
             Jedis jedis=RedisManager.getJedis();//连接获取jedis实列
             while(true) {
                 jedis.watch(key);
                 //判断获得锁的线程和当前线程redis中存的值一样
                 if(value.equals(jedis.get(key))) {
                     Transaction transaction=jedis.multi();//去开启事务
                     transaction.del(key);//删除key
                     List<Object> list=transaction.exec();//执行事务
                     if(list==null) {
                         continue;
                     }
                     return true;
                 }
                 jedis.unwatch();
                 break;
             }
         } catch (Exception e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return false;
     }
     /**
      * 测试
      * @param args
      */
     public static void main(String args[]) {
         RedisLock lock=new RedisLock();
         String lookId=lock.getLock("aaa", 10000);

         if(null!=lookId) {
             System.out.println("获取锁成功");
         }

         System.out.println("失败");
         String mm=lock.getLock("aaa", 10000);
         System.out.println(mm);
     }
 }

redis中有一个setNx命令,这个命令只有在key不存在的情况下为key设置值