一篇文章告诉你怎样用Redis实现分布式锁?(二)

开课吧开课吧锤锤2021-03-30 10:07

    Java编程语言是一种简单、面向对象、分布式、解释型、健壮安全、与系统无关、可移植、高性能、多线程和动态的语言。如今Java已经广泛应用于各个领域的编程开发。

Java

    加锁

    整体加锁的逻辑比较简单,大家基本上都能看懂,不过我拿到当前时间去减开始时间的操作感觉有点笨,System.currentTimeMillis()消耗很大的。

/** 
* 加锁
 * 
* @param id
 * @return
 */public boolean lock(String id) {  
  Long start = System.currentTimeMillis();    
try {       
 for (; ; ) {           
 //SET命令返回OK ,则证明获取锁成功          
  String lock = jedis.set(LOCK_KEY, id, params);          
  if ("OK".equals(lock)) {            
    return true;        
    }      
      //否则循环等待,在timeout时间内仍未获取到锁,则获取失败          
  long l = System.currentTimeMillis() - start;         
   if (l >= timeout) {          
      return false;       
    }          
  try {          
      Thread.sleep(100);       
     } catch (InterruptedException e) {         
       e.printStackTrace();     
       }     
   }   
 } finally {   
    jedis.close();   
 }
}

    System.currentTimeMillis消耗大,每个线程进来都这样,我之前写代码,就会在服务器启动的时候,开一个线程不断去拿,调用方直接获取值就好了,不过也不是最优解,日期类还是有很多好方法的。

@Servicepublic 
class TimeServcie {   
 private static long time;   
 static {       
 new Thread(new Runnable(){    
        @Override            
public void run() {
                while (true){
                  
try {                        
Thread.sleep(5);
                    } catch (InterruptedException e) {                        
e.printStackTrace();                   
 }                   
 long cur = System.currentTimeMillis();                   
setTime(cur);                
}            
}        
}).start();   
 }    
public static long getTime() {       
return time;    
}    
public static void setTime(long time) {        
TimeServcie.time = time;    
}
}


    解锁

    解锁的逻辑更加简单,就是一段Lua的拼装,把Key做了删除。

    你们发现没,我上面加锁解锁都用了UUID,这就是为了保证,谁加锁了谁解锁,要是你删掉了我的锁,那不乱套了嘛。

    LUA是原子性的,也比较简单,就是判断一下Key和我们参数是否相等,是的话就删除,返回成功1,0就是失败。

/** 
* 解锁 
* 
* @param id 
* @return
 */public boolean unlock(String id) {
    String script =
            "if redis.call('get',KEYS[1]) == ARGV[1] then" +
                    "   return redis.call('del',KEYS[1]) " +
                    "else" +
                   "   return 0 " +
                    "end";    try {
        String result = jedis.eval(script, Collections.singletonList(LOCK_KEY), Collections.singletonList(id)).toString();
        return "1".equals(result) ? true : false;
    } finally {
        jedis.close();
    }
}

    以上内容由开课吧老师敖丙提供,更多Java教程尽在开课吧广场Java教程频道。

有用
分享