java使用redis实现分布式锁

来源:互联网 发布:java年月日时分秒格式 编辑:程序博客网 时间:2024/06/05 09:49

直接贴上代码

/** * @param subKey  set Key name * @param timeout  get lock timeout,if not get, * @param unit   time unit * @param sValue   * @return */ public static boolean tryLock(String subKey, String sValue,long timeout, TimeUnit unit) {    String key =  subKey;    Jedis jedis =  null;try {jedis = getResource(); if (jedis == null) {return Boolean.FALSE;}long nano = System.nanoTime();do {logger.debug("try lock key: " + key);Long i = jedis.setnx(key, sValue);  //此处可能出现死锁(执行setnx后,redis crash ,key一直存在)if (i == 1) {jedis.expire(key, 5);//锁失效时间5秒logger.debug("get lock, key: " + key + " , expire in "+ 2 + " seconds.");return Boolean.TRUE;} //解决出现死锁问题  可优化为 getset方式 重新设置值// key存在, 获取key的内容值, 值为nanotime 纳秒   ,当前的时间 - key的值>锁 锁定时间,此时可获取锁String value = jedis.get(key);if (StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value)&&(System.nanoTime()-Long.valueOf(value))>TimeUnit.SECONDS.toNanos(5)) {set(key, value, 5); //设置key 5秒过期  自动释放return Boolean.TRUE;}if (timeout == 0) { // 取不到锁时,不等待,直接返回.break;}Thread.sleep((int)(50*Math.random()+50));// 等待50- 100毫秒  避免不同线程竞争时间相同} while ((System.nanoTime() - nano) < unit.toNanos(timeout));// 取不到锁时等待,直到timeoutif (logger.isInfoEnabled()) {String desc = jedis.get(key);logger.debug("key: " + key+ " locked by another business:" + desc);}return Boolean.FALSE;}catch (Exception e) {logger.error(e.getMessage(), e);} finally {returnResource(jedis);//释放连接}  return Boolean.FALSE;   }      /** 获取key对应值,对比值内容, 相同则删除,释放锁,避免删除其他线程已经获取的锁  * @param subKey  * @param sValue  */public static boolean unLock(String subKey,String sValue) {String key =  subKey;Jedis jedis = null;try {jedis = getResource(); if (jedis == null) {return false;}String str = jedis.get(subKey);if (str.equals(sValue)) {jedis.del(key);logger.debug("release lock, keys :" + key);return true;}else {logger.debug("the key is not exist,key : " + key);}} catch (Exception e) {logger.error(e.getMessage(), e);} finally {returnResource(jedis);//释放连接}return false;}public static void main(String args[]){String sValue = String.valueOf(System.nanoTime());String subKey = "productId";try {//  5000毫秒 boolean lock = tryLock(subKey, sValue, 5000, TimeUnit.MILLISECONDS);if (lock) {//do job 相关业务逻辑}} catch (Exception e) {e.printStackTrace();}finally{unLock(subKey, sValue);}}


0 0
原创粉丝点击