redis分布式锁练习【我】
package redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class RedisLock { public static void main(String[] args) { JedisPool jedisPool = new JedisPool("127.0.0.1", 6379); // 从连接池中获取一个jedis对象 Jedis jedis = jedisPool.getResource(); //简单加redis分布式锁的方式 boolean lock = false; String key = "mylock"; String value = System.currentTimeMillis()+""; try { //50秒自动解锁 String setResult = jedis.set(key,value , "nx", "ex", 50L); long startTime = 0; if (setResult!=null) { lock = true; startTime = System.currentTimeMillis(); } //没有获取到锁,退出 if (!lock) { return; } //执行到了这一步说明已经获取到锁 // doSth long endTime = System.currentTimeMillis(); //如果超时解锁 if ((endTime-startTime)>5000) { //打印日志 System.out.println("出现超时解锁-----------key:"+key); } } catch (Exception e) { e.printStackTrace(); }finally { //这里是为了避免超时后,释放掉其他线程的同名锁 //但是有个问题,就是下面的代码不是原子操作,可能会有问题,这里忽略 String s = jedis.get(key); if (value.equals(s)) { //释放锁 jedis.del(key); } } } }
package redis; import java.util.HashMap; import java.util.Map; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class RedisReentrantLock { private ThreadLocal<Map<String,Integer>> lockers = new ThreadLocal<>(); private Jedis jedis; public RedisReentrantLock(Jedis jedis) { super(); this.jedis = jedis; } private boolean _lock(String key) { return jedis.set(key,"" , "nx", "ex", 5L)!=null; } private void _unlock(String key) { jedis.del(key); } private Map<String, Integer> currentLockers(){ Map<String, Integer> refs = lockers.get(); if (refs !=null) { return refs; } lockers.set(new HashMap<String, Integer>()); return lockers.get(); } public boolean lock(String key) { Map<String, Integer> refs = currentLockers(); Integer refCnt = refs.get(key); if (refCnt!=null) { refs.put(key, refCnt+1); return true; } boolean ok = this._lock(key); if (!ok) { return false; } refs.put(key, 1); return true; } public boolean unlock(String key) { Map<String, Integer> refs = currentLockers(); Integer refCnt = refs.get(key); if (refCnt == null) { return false; } refCnt -= 1; if (refCnt>0) { refs.put(key, refCnt); }else { refs.remove(key); this._unlock(key); } return true; } public static void main(String[] args) { JedisPool jedisPool = new JedisPool("127.0.0.1", 6379); // 从连接池中获取一个jedis对象 Jedis jedis = jedisPool.getResource(); RedisReentrantLock redisLock = new RedisReentrantLock(jedis); System.out.println(redisLock.lock("lock1")); System.out.println(redisLock.lock("lock1")); System.out.println(redisLock.unlock("lock1")); System.out.println(redisLock.unlock("lock1")); } }