您的位置:首页 > 数据库 > Redis

用redis实现分布式锁

2018-01-12 18:48 393 查看
Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系。redis的SETNX命令可以方便的实现分布式锁。

maven依赖:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>


初始化jedis

@Configuration
public class JedisConfig {
@Bean
@Order(1)
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(10);
poolConfig.setMaxTotal(30);
return poolConfig;
}

@Bean
@Order(2)
public JedisPool jedisPool(JedisPoolConfig jedisPoolConfig) {
return new JedisPool(jedisPoolConfig,
"192.168.1.81",

4000
6379,
3000,
"password");
}
@Bean
@Order(3)
public JedisLock jedisLock(JedisPool jedisPool){
JedisLock jedisLock = new JedisLock();
jedisLock.setJedisPool(jedisPool);
return jedisLock;
}
}


public class JedisLock {
private static final String key = "LOCK";
private static final String      SUCCESS         = "OK";
JedisPool jedisPool;
public String getLock(int lockTimout){
String value = null;
try {
Jedis jedis = jedisPool.getResource();
long end = System.currentTimeMillis() + lockTimout;
Random random = new Random();
value = UUID.randomUUID().toString();
while (System.currentTimeMillis()<end){
String response = jedis.set(key, value, "NX", "EX", lockTimout);
if (SUCCESS.equals(response)){
//成功获取锁,用完记得释放
System.out.println("成功获得锁 response:"+response+",value:"+value);
return value;
}
TimeUnit.MILLISECONDS.sleep(Math.max(20, random.nextInt(100)));
}
}catch (Exception e){
e.printStackTrace();
}
System.out.println("超时未获得锁。。。。");
return null;
}
public boolean releaseLock(String value){
try {
Jedis jedis = jedisPool.getResource();
jedis.watch(key);
if (StringUtils.pathEquals(value,jedis.get(key))){
Transaction transaction = jedis.multi();
transaction.del(key);
List<Object> list = transaction.exec();
jedis.unwatch();
if (null != list){
return true;
}
}
}catch (Exception e){
e.printStackTrace();
}
return false;
}

/**
* Setter method for property <tt>jedisPool</tt>.
*
* @param jedisPool value to be assigned to property jedisPool
*/
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
}


测试:

public class JedisTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JedisConfig.class);
JedisLock jedisLock = (JedisLock) context.getBean("jedisLock");

String lock = jedisLock.getLock(10000);
System.out.println(lock);
String lock1 = jedisLock.getLock(1000);
System.out.println(lock1);

boolean b = jedisLock.releaseLock(lock);
System.out.println("释放锁:"+b);
}
}


这只是一个简单的小例子,curator(基于zookeeper)已经封装好了,可以直接使用
http://blog.csdn.net/zyj_2012/article/details/78842908 href="http://blog.csdn.net/zyj_2012/article/details/78842908" target=_blank>点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: