美食网站设计欣赏,wordpress无法html,wordpress 文章付费,提供免费服务器的网站1. setnx(lockkey, 当前时间过期超时时间) #xff0c;如果返回1#xff0c;则获取锁成功#xff1b;如果返回0则没有获取到锁#xff0c;转向2。2. get(lockkey)获取值oldExpireTime #xff0c;并将这个value值与当前的系统时间进行比较#xff0c;如果小于当前系统时间…1. setnx(lockkey, 当前时间过期超时时间) 如果返回1则获取锁成功如果返回0则没有获取到锁转向2。2. get(lockkey)获取值oldExpireTime 并将这个value值与当前的系统时间进行比较如果小于当前系统时间则认为这个锁已经超时可以允许别的请求重新获取转向3。3. 计算newExpireTime当前时间过期超时时间然后getset(lockkey, newExpireTime) 会返回当前lockkey的值currentExpireTime。4. 判断currentExpireTime与oldExpireTime 是否相等如果相等说明当前getset设置成功获取到了锁。如果不相等说明这个锁又被别的请求获取走了那么当前请求可以直接返回失败或者继续重试。5. 在获取到锁之后当前线程可以开始自己的业务处理当处理完毕后比较自己的处理时间和对于锁设置的超时时间如果小于锁设置的超时时间则直接执行delete释放锁如果大于锁设置的超时时间则不需要再锁进行处理。代码如下/** * 带超时时间的锁 * * param lockKey 锁的键值 * param timeUnit 锁的时间单位 * param timeout 锁的时间长度 * param relyOnRedisAvailable 是否依赖redis可用性 * true则redis不可用或异常情况下返回加锁失败 * false则redis不可用或异常情况下返回加锁成功。 * return 是否添加锁成功 */Overridepublic boolean lock(String lockKey, TimeUnit timeUnit, long timeout, boolean relyOnRedisAvailable) {//获取当前时间 long currentTimeMillis System.currentTimeMillis(); String repeatSign UUID.randomUUID().toString().replace(-, );//重复标记 //获取超时时间的ms long lockTimeMs timeUnit.toMillis(timeout);long setNx;try {//这里我们以 超时时间为value标记 String setLockValue String.valueOf(currentTimeMillis lockTimeMs)repeatSign; setNx redisClientUtil.setnx(lockKey, setLockValue);logger.info(键值[{}]设置的setNx为:{}, setLockValue为:{}, lockKey, setNx, setLockValue); } catch (Exception e) {logger.error({}设置锁异常,lockKey,e); pubEvent(lockKey,e);return true; }//如果成功了那么我们就设置超时时间 if (setNx 1 ) {logger.info(键值{}获取redis锁成功,lockKey);try {redisClientUtil.expire(lockKey, (int)timeUnit.toSeconds(timeout)); } catch (Exception e) {logger.error({}设置超时时间异常异常信息为,lockKey,e); }return true; }//以下是不成功的处理情况即 setNx 等于0的时候我们先获取旧的值 String lockValue redisClientUtil.getValueByKey(lockKey);logger.info(键值[{}]设置的lockValue为:{}重复标记为:{}, lockKey, lockValue, repeatSign);if (StrUtil.isBlank(lockValue)) {//如果锁value为空直接返回成功 return true; }if(lockValue.contains(repeatSign)){//如果锁value包含重复标记则说明其为本次设置直接返回成功 return true; } String lockTime lockValue.substring(0, lockValue.indexOf(|));//锁超时时间 if (null lockTime) {logger.warn(键值[{}]获取到时间戳为空, 按照获取成功返回!, lockKey);return true; } else {try {logger.info(键值[{}]redis存储的时间戳:{}, 格式化后:{}, lockKey, lockTime, DateUtil.dateToString(new Date(Long.valueOf(lockTime)), DateUtil.DEFAULT_TIMESTAMP_FORMAT)); } catch (Exception e) {logger.warn(键值[{}]redis存储的时间戳:{}, 格式化时出现异常不影响流程, lockKey, lockTime, e); } }if (lockTime ! null Long.valueOf(lockTime) System.currentTimeMillis() ) { String oldValue redisClientUtil.getSet(lockKey, String.valueOf(currentTimeMillis lockTimeMs) | repeatSign); String oldLockTime oldValue.substring(0, lockValue.indexOf(|));//锁超时时间 //将两次获取的值对比这里也就是文章第五条如果相等说明没有被其他线程修改 if (oldValue ! null oldLockTime.equals(lockTime)) {//这里用该还要在设置一次超时时间可以用lua 脚本保持一致性 return true; } }return false;}