通过redis实现对于分布式的环境下的并发管理

2018-03-01 11:15:59来源:https://www.jianshu.com/p/8a0c2ac59596作者:H_Man人点击

分享


使用定时器时,部署到多个节点,共同访问一个库,导致任务重复执行,然后想到了使用redis来实现锁原理.


import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import java.util.concurrent.TimeUnit;
/**
* 通过redis实现对于分布式的环境下的并发管理(通过redis锁实现并发处理)
*/
public class RedisDistributionLock implements DistributionLock {
private long lockTimeout;
private final RedisTemplate<String, RedisLockObject> redisTemplate;
private final String lockKey;
private final RedisSerializer keyRedisSerializer;
private final RedisSerializer valueRedisSerializer;
public RedisDistributionLock(RedisTemplate<String, RedisLockObject> redisTemplate, String key, long timeout) {
this.redisTemplate = redisTemplate;
this.lockTimeout = timeout;
this.lockKey = key;
this.keyRedisSerializer = redisTemplate.getKeySerializer();
this.valueRedisSerializer = redisTemplate.getValueSerializer();
}
//尝试获取一次锁
public synchronized boolean tryLock() {
long currentTime = System.currentTimeMillis();
Long lock_timeout = currentTime + lockTimeout;
if (redisTemplate.execute(new LockRedisCallBack(this.lockKey, lock_timeout))) {
redisTemplate.expire(lockKey, lockTimeout, TimeUnit.MILLISECONDS);
return true;
} else {
RedisLockObject redisLockObject = null;
try {
Object object = redisTemplate.opsForValue().get(lockKey);
if (object != null) {
redisLockObject = (RedisLockObject) redisTemplate.opsForValue().get(lockKey);
}
} catch (Exception err) {
redisTemplate.delete(lockKey);
err.printStackTrace();
}
if (redisLockObject != null && (redisLockObject.getTimeout() < currentTime)) {
long oldTimeout = redisLockObject.getTimeout();
redisLockObject.setTimeout(lockTimeout);
RedisLockObject oldRedisLockObject = (RedisLockObject) redisTemplate.opsForValue().getAndSet(lockKey, redisLockObject);
if (oldRedisLockObject != null && oldRedisLockObject.getTimeout() == oldTimeout) {
redisTemplate.expire(lockKey, lockTimeout, TimeUnit.MILLISECONDS);
return true;
}
}
}
return false;
}
/**
* 加锁 取到锁加锁,取不到锁就返回
*
* @return
*/
@Override
public synchronized long lock() {
while (true) {
if (tryLock()) {
return System.currentTimeMillis() + lockTimeout;
}
try {
Thread.sleep(10);
} catch (Exception err) {
err.printStackTrace();
}
}
}
/**
* 解锁
*/
@Override
public synchronized void unlock() {
RedisLockObject redisLockObject = (RedisLockObject) redisTemplate.opsForValue().get(lockKey);
if (redisLockObject != null) {
redisTemplate.delete(lockKey);
}
}

@SuppressWarnings("rawtypes")
private class LockRedisCallBack implements RedisCallback<Boolean> {
private long timeOut;
public LockRedisCallBack(String key, long timeOut) {
this.timeOut = timeOut;
}

@SuppressWarnings("unchecked")
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
RedisLockObject redisLockObject = new RedisLockObject();
redisLockObject.setTimeout(timeOut);
byte[] value = valueRedisSerializer.serialize(redisLockObject);
byte[] key = valueRedisSerializer.serialize(lockKey);
return connection.setNX(key, value);
}
}
}

public interface DistributionLock {
public long lock();
public void unlock();
}







最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台