通过Redis实现分布式锁,主要使用了如下命令:
SETNX key val
当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
expire key timeout
为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
delete key
删除key
实现使用的是jedis来连接Redis。
建立一个MAVEN工程,然后,pom文件引入jedis
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency>
核心代码如下:
package redis.test.redislock; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class DistributedLock { private final JedisPool jedisPool; private final String LOCK_NAME = "redisLock"; public DistributedLock(JedisPool jedisPool) { this.jedisPool = jedisPool; } public long getLock(String lockValue) { Jedis jedis = null; long exist = 0; try { jedis = jedisPool.getResource(); exist = jedis.setnx(LOCK_NAME, lockValue); } finally { if(jedis != null) { jedis.close(); } } return exist; } public String getLockValue() { String name = ""; Jedis jedis = null; try { jedis = jedisPool.getResource(); name = jedis.get(LOCK_NAME); } finally { if(jedis != null) { jedis.close(); } } return name; } public long expireTime(int expireTime) { long isSuccess = 0; Jedis jedis = null; try { jedis = jedisPool.getResource(); isSuccess = jedis.expire(LOCK_NAME, expireTime); } finally { if(jedis != null) { jedis.close(); } } return isSuccess; } public long releaseLock(String lockValue) { long isSuccess = 0; Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.watch(LOCK_NAME); if(lockValue.equals(jedis.get(LOCK_NAME))) { isSuccess = jedis.del(LOCK_NAME); } } finally { if(jedis != null) { jedis.close(); } } return isSuccess; } }
测试Demo
package redis.test.redislock; import redis.clients.jedis.JedisPool; public class TestLock implements Runnable { public static void main(String[] args) { TestLock testLock = new TestLock(); for (int i = 0; i < 50; i++) { Thread threadA = new Thread(testLock); threadA.start(); } } public void run() { JedisPool jedisPool = new JedisPool("10.185.156.190", 6379); DistributedLock distributedLock = new DistributedLock(jedisPool); if(1 == distributedLock.getLock(Thread.currentThread().getName())) { System.out.println("set expire time : " + (1 == distributedLock.expireTime(1000))); System.out.println("get value : " + distributedLock.getLockValue()); distributedLock.releaseLock(Thread.currentThread().getName()); } else { System.out.println("get lock fail."); } } }