Redis实现分布式锁

Redis实现分布式锁优点:redis单线程(通过队列将并发变成串行,同一刻只有一个操作可以执行),有getset, setnx(set if not exist)等便于实现的方法


问题:

1. 简单的get & set方法为何不能实现:并发情况下会有锁竞争。参考http://blog.csdn.net/ugg/article/details/41894947

Redis实现分布式所需要注意的点:

1. 尽量减少锁内处理流程,避免在处理过程锁失效。

2.要有锁过期机制,避免其他客户端无法获取锁时,造成死锁崩溃。

3.尽量使得 锁内流程处理时间 < 锁过期时间(value值) < 锁失效时间(key的expire)

(这是锁的意义:锁应该用时获取,不用时释放,避免等待锁自己的超时释放。

Java&Jedis实现参考:

 public DistributedLock acquireLock(String key, long timeout) {
		if (timeout > 10 * 1000) {
			throw new IllegalArgumentException("Lock time can not be more than 10 seconds.");
		}
		StringRedisTemplate stringRedisTemplate = RedisTemplateContext.getStringRedisTemplate(RedisHosts.SINGLE_FIRST);
		BoundValueOperations<String, String> lockOpt = stringRedisTemplate.boundValueOps(key);
		long currentTime = System.currentTimeMillis();
		long nextLockTimeout = currentTime + timeout + 1;
		DistributedLock lockResult = new DistributedLock();
		lockResult.setKey(key);
		lockResult.setAcqLockTime(nextLockTimeout);
		lockResult.setAcquiredSucc(false);
		if (lockOpt.setIfAbsent(String.valueOf(nextLockTimeout))) {
			lockOpt.expire(10, TimeUnit.MINUTES);
			lockResult.setAcquiredSucc(true);
			return lockResult;
		}
		String lockTimeInRedis = lockOpt.get();
		if (lockTimeInRedis == null || currentTime > Long.parseLong(lockTimeInRedis)) {
			String preLockTime = lockOpt.getAndSet(String.valueOf(nextLockTimeout)); 
			if (isTimeEqual(lockTimeInRedis, preLockTime)) { //此处对比,避免getset期间有其它对象获取到锁
				lockOpt.expire(10, TimeUnit.MINUTES);
				lockResult.setAcquiredSucc(true);
				return lockResult;
			}
		}
		return lockResult;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值