java使用redis实现分布式锁

    xiaoxiao2021-03-25  53

    直接贴上代码

    /** * @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));// 取不到锁时等待,直到timeout if (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); } }

    转载请注明原文地址: https://ju.6miu.com/read-39326.html

    最新回复(0)