一个纯的java-redis锁,因为有更好的,暂时就只记录一下
2018-01-15 10:15
585 查看
找了很长时间,左试右试的搞了一个redis锁出来,但是被一个更好的方案取代了,有点郁闷,在此记录一下。
开始是因为redis的操作原子性问题,没有用redis自带的key过期,因为setnx 和expire是两个方法,无法保持强一致性,在高并发时候是致命的。而且保留着对redis的自带过期的不信任(这里补充一下,查了资料后发现redis的自带过期还是不错的,两种过期方式,一个是在get的时候判断key是否过期,一个是在空闲时间流出25%cpu时间随机拿带过期的key进行随机淘汰。不过可能在超大的吞吐量的时候可能会因为淘汰不及时,稍微占点内存),就选择了利用value来实现。
不过后来大神从spring的git里找来一个好方法,就是利用redistemplate的execute,把命令当脚本执行,保证了redis 的setnx和过期的原子性,直接我这个方案就不合适了。还是要多了解api啊。
开始是因为redis的操作原子性问题,没有用redis自带的key过期,因为setnx 和expire是两个方法,无法保持强一致性,在高并发时候是致命的。而且保留着对redis的自带过期的不信任(这里补充一下,查了资料后发现redis的自带过期还是不错的,两种过期方式,一个是在get的时候判断key是否过期,一个是在空闲时间流出25%cpu时间随机拿带过期的key进行随机淘汰。不过可能在超大的吞吐量的时候可能会因为淘汰不及时,稍微占点内存),就选择了利用value来实现。
@Component public class NamedLock { private static final int AUTO_RELEASE_AFTER_MINUTES = 10; @Autowired private RedisTemplate redisTemplate; public boolean tryLock(String name,long useless) { DateTime now = DateTime.now(); Boolean tryLock = redisTemplate.opsForValue().setIfAbsent(name, now.getMillis()); if (tryLock) { return true; } else { Long lockTime = (Long) redisTemplate.opsForValue().get(name); if (lockTime == null) { return redisTemplate.opsForValue().setIfAbsent(name, now.getMillis()); } if (now.minusMinutes(AUTO_RELEASE_AFTER_MINUTES).isAfter(lockTime)) { Long originTime = (Long) redisTemplate.opsForValue().getAndSet(name, now.getMillis()); if (originTime == null || originTime.equals(lockTime)) return true; else return false; } else { return false; } } } public boolean isLocked(String name) { return redisTemplate.opsForValue().get(name) == null; } public void releaseLock(String name) { Long lockTime = (Long) redisTemplate.opsForValue().get(name); if(lockTime != null && DateTime.now().minusMinutes(AUTO_RELEASE_AFTER_MINUTES).isBefore(lockTime)){ redisTemplate.delete(name); } return; } }
不过后来大神从spring的git里找来一个好方法,就是利用redistemplate的execute,把命令当脚本执行,保证了redis 的setnx和过期的原子性,直接我这个方案就不合适了。还是要多了解api啊。
相关文章推荐
- java框架学习,记录一下,给自己一个动力
- 一个博客上的KVM文章,暂时看不完,记录一下
- 记录一下SparkStreaming中因为使用redis做数据验证而导致数据结果不对的问题
- 更好的一个简繁体转换。记录一下
- 最近要复制一个php的产品成java,简单记录一下php的知识
- 写了一个Java读取XML文件的工具类,做一下笔记!
- [学习笔记]Java代码构建一个线程池的自己学习写的实例,用这个你会更好的理解文章内容
- java写循环,犯了一个小错误,记录下来以鞭策
- 写了一个Java读取XML文件的工具类,做一下笔记!
- SolarWinds Orion Network Performance Monitor --看我一个同事用这个东东,特此记录一下,可以统计服务器的cpu使用情况。
- 同一个Socket实例第二次无法接收服务端数据!! (暂时占用一下首页,请多包涵,该问题困扰我两天了)
- 刚看了一个程序,并写了一下,然后用Java 再写了一下
- 关于Hibernate中fatch=eager的bag集合(一个java List)使用Criteria查询出现重复记录的问题
- 今天大致了解了一下Java Script,实现了一个JS版的小计算器
- 在做一个大型java项目,从现在起记录一些技术应用框架配置,一、svn+apace+权限配置
- 写了一个通用的用户选择页面,记录一下调用方法
- js的一个托拽功能,网上找的,记录一下
- 查找一个表中重复记录的存储过程(因为数据是从Excele中导到表中的, 表还没有建立主Key)
- js判断checkbox选中(记录一下,一个小问题引发的)
- 终于在csdn上安家了!这个博客将作为我学习java历程,记录我心得的一个地方