使用Redis的 SETNX 命令可以实现分布式锁
SETNX key value
返回值
返回整数,具体为
- 1,当 key 的值被设置
- 0,当 key 的值没被设置
分布式锁使用
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * @Author: feng * @Date: 2019/5/25 21:54 * @Description: */ public class RedisManager { private static JedisPool jedisPool; static { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(18); jedisPoolConfig.setMaxIdle(5); jedisPool = new JedisPool(jedisPoolConfig,"127.0.0.1",6379,5000); } public static Jedis getJedis() throws Exception { if (null != jedisPool){ return jedisPool.getResource(); } throw new Exception("Jedispool was not init"); } }
import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; import java.util.List; /** * @Author: feng * @Date: 2019/5/25 22:04 * @Description: */ public class RedisLock { public String getLock(String key, int timeout) { Jedis jedis = null; try { jedis = RedisManager.getJedis(); // String value = UUID.randomUUID().toString(); //以当前线程id作为value String value = String.valueOf(Thread.currentThread().getId()); long end = System.currentTimeMillis() + timeout; while (System.currentTimeMillis() < end) { if (jedis.setnx(key, value) == 1) { jedis.expire(key, timeout); return value; } if (jedis.ttl(key) == -1) { jedis.expire(key, timeout); } Thread.sleep(500); } } catch (Exception e) { e.printStackTrace(); } finally { jedis.close(); } return null; } public boolean releaseLock(String key, String value) { Jedis jedis = null; try { jedis = RedisManager.getJedis(); while (true) { jedis.watch(key); System.out.println(jedis.get(key)); if (value.equals(jedis.get(key))) { Transaction transaction = jedis.multi(); transaction.del(key); List<Object> list = transaction.exec(); if (list == null) { continue; } } jedis.unwatch(); return true; } } catch (Exception e) { e.printStackTrace(); } finally { jedis.close(); } return false; } public static void main(String[] args) { RedisLock redisLock = new RedisLock(); String thredId = redisLock.getLock("test", 1000); System.out.println("返回值value:" + thredId); boolean b = redisLock.releaseLock("test", String.valueOf(Thread.currentThread().getId())); System.out.println(b); } }