个人笔记|ReentrantLock 可重入锁

可重入性是指线程在持有锁的情况下再次请求加锁,如果一个锁支持同一个线程的多次加锁,那么这个锁就是可重入的。比如 Java 语言里有个 ReentrantLock 就是可重入锁。如果Redis 分布式锁要支持可重入,需要对客户端的 set 方法进行包装,使用线程的 Threadlocal 变量存储当前持有锁的计数。
代码如下:

public class RedisWithReentrantLock {private ThreadLocal lockers = new ThreadLocal<>(); private Jedis jedis; public RedisWithReentrantLock(Jedis jedis) { 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 currentLockers(){ Map refs = lockers.get(); if (null != refs){ return refs; } lockers.set(new HashMap<>()); return lockers.get(); }public boolean lock(String key){ Map refs = currentLockers(); Integer refCnt = refs.get(key); if (null != refCnt){ 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 refs = currentLockers(); Integer refCnt = refs.get(key); if (null ==refCnt){ return false; } refCnt -= 1; if (refCnt > 0){ refs.put(key, refCnt); }else { refs.remove(key); this._lock(key); } return true; }/** public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); RedisWithReentrantLock redisWithReentrantLock = new RedisWithReentrantLock(jedis); System.out.println(redisWithReentrantLock.lock("TestLock")); System.out.println(redisWithReentrantLock.lock("TestLock")); System.out.println(redisWithReentrantLock.unlock("TestLock")); System.out.println(redisWithReentrantLock.unlock("TestLock")); } **/}

【个人笔记|ReentrantLock 可重入锁】

    推荐阅读