A Comprehensive Guide to Redisson Distributed Locks in Java
This article explains Redisson's various distributed lock mechanisms—including watchdog, reentrant lock, multi‑lock, read‑write lock, semaphore, RedLock, and CountDownLatch—detailing their principles, usage patterns, code examples, and best‑practice recommendations for robust backend concurrency control.
1. Introduction
Redisson extends Redis with a Swiss‑army‑knife‑like API for Java developers, offering multiple distributed lock types that improve safety and convenience compared to native Redis commands.
2. Watchdog
The watchdog automatically renews a lock before it expires, preventing premature release when business logic runs longer than the default 30‑second timeout.
2‑1. Why a watchdog?
Prevents lock loss if business exceeds the expiration time.
Ensures lock is released if the client crashes.
No need to manually calculate execution time.
2‑2. How it works
Lock acquisition sets a 30‑second TTL.
A background task checks every 10 seconds; if the lock is still held, it extends the TTL.
Lock is released when the business finishes or the client disconnects.
2‑3. Configuring the watchdog
<code>Config config = new Config();
config.setLockWatchdogTimeout(30000L); // milliseconds, default 30 s
RedissonClient redisson = Redisson.create(config);
// Or specify timeout per lock
lock.lock(60, TimeUnit.SECONDS); // watchdog uses 60 s cycle
</code>3. Reentrant Lock
Provides a distributed version of Java's ReentrantLock , supporting thread‑safety across JVMs, automatic renewal, fair/non‑fair modes, and timeout handling.
3‑1. Features
Thread‑safe across different JVMs.
Watchdog‑based auto‑renewal.
Fair and non‑fair acquisition options.
Timeout to avoid indefinite waiting.
3‑2. Usage examples
Basic (blocking)
<code>RLock lock = redisson.getLock("orderLock");
lock.lock();
try {
// business logic
} finally {
lock.unlock();
}
</code>Try‑lock (non‑blocking)
<code>if (lock.tryLock(3, 30, TimeUnit.SECONDS)) {
try {
// business logic
} finally {
lock.unlock();
}
} else {
log.warn("Failed to acquire lock, retry later");
}
</code>Async acquisition
<code>RFuture<Void> lockFuture = lock.lockAsync();
lockFuture.whenComplete((res, ex) -> {
if (ex == null) {
try {
// async business
} finally {
lock.unlock();
}
}
});
</code>3‑3. Fair lock
<code>RLock fairLock = redisson.getFairLock("myFairLock");
fairLock.lock();
try {
// business logic
} finally {
fairLock.unlock();
}
</code>3‑4. Non‑fair lock
<code>RLock nonFairLock = redisson.getLock("hotItemLock");
if (nonFairLock.tryLock(50, TimeUnit.MILLISECONDS)) {
try {
// flash‑sale logic
} finally {
nonFairLock.unlock();
}
}
</code>3‑5. Reentrant lock internals (Lua pseudocode)
<code>-- Acquire lock
if redis.call('exists', KEYS[1]) == 0 then
redis.call('hset', KEYS[1], ARGV[2], 1);
redis.call('pexpire', KEYS[1], ARGV[1]);
return nil;
end
if redis.call('hexists', KEYS[1], ARGV[2]) == 1 then
redis.call('hincrby', KEYS[1], ARGV[2], 1);
redis.call('pexpire', KEYS[1], ARGV[1]);
return nil;
end
return redis.call('pttl', KEYS[1]);
</code>4. Multi‑Lock (联锁)
Combines several locks into an atomic "all‑or‑nothing" operation, useful for distributed transactions across multiple resources.
4‑1. Basic usage
<code>RLock lock1 = redisson.getLock("order_lock");
RLock lock2 = redisson.getLock("stock_lock");
RLock lock3 = redisson.getLock("coupon_lock");
RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2, lock3);
if (multiLock.tryLock(3, 30, TimeUnit.SECONDS)) {
// process order, update stock, use coupon
} else {
log.warn("One resource refused the lock");
}
finally {
multiLock.unlock();
}
</code>4‑2. Advanced dynamic construction
<code>List<RLock> locks = resourceIds.stream()
.map(id -> redisson.getLock("resource_" + id))
.collect(Collectors.toList());
RedissonMultiLock dynamicLock = new RedissonMultiLock(locks.toArray(new RLock[0]));
</code>4‑3. Pitfalls
Avoid acquiring locks in different orders (deadlock risk).
Do not mix lock types (fair vs non‑fair) in the same multi‑lock.
Ensure all locks are acquired; otherwise roll back completely.
5. Read‑Write Lock
Allows concurrent reads while writes are exclusive, ideal for read‑heavy scenarios.
<code>RReadWriteLock rwLock = redisson.getReadWriteLock("libraryBook_123");
// Read
rwLock.readLock().lock();
try {
Book book = getBookFromDB(123);
} finally {
rwLock.readLock().unlock();
}
// Write
rwLock.writeLock().lock();
try {
updateBookInDB(123, newVersion);
} finally {
rwLock.writeLock().unlock();
}
</code>6. Semaphore
Controls concurrency by limiting the number of permits.
<code>RSemaphore semaphore = redisson.getSemaphore("apiLimit");
semaphore.trySetPermits(10);
semaphore.acquire();
try {
callLimitedAPI();
} finally {
semaphore.release();
}
// Non‑blocking try
if (semaphore.tryAcquire()) {
try { /* work */ } finally { semaphore.release(); }
} else {
log.warn("System busy, try later");
}
</code>7. RedLock
Implements the Redlock algorithm across multiple independent Redis nodes to achieve higher availability.
<code>RLock lock1 = redissonClient1.getLock("lock");
RLock lock2 = redissonClient2.getLock("lock");
RLock lock3 = redissonClient3.getLock("lock");
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
boolean locked = redLock.tryLock(100, 30, TimeUnit.SECONDS);
if (locked) {
doCriticalWork();
}
redLock.unlock();
</code>8. CountDownLatch
Coordinates multiple tasks, blocking until a predefined count reaches zero.
<code>// Coordinator
RCountDownLatch latch = redisson.getCountDownLatch("batchTaskLatch");
latch.trySetCount(5);
// Workers
RCountDownLatch workerLatch = redisson.getCountDownLatch("batchTaskLatch");
workerLatch.countDown();
// Coordinator waits
latch.await();
System.out.println("All tasks completed!");
</code>9. Summary
Redisson offers a rich set of distributed synchronization primitives—watchdog, reentrant lock, fair/non‑fair locks, multi‑lock, read‑write lock, semaphore, RedLock, and CountDownLatch—each suited to specific backend scenarios; selecting the right primitive and configuring lock granularity and TTL are essential to avoid deadlocks and performance bottlenecks.
Zhuanzhuan Tech
A platform for Zhuanzhuan R&D and industry peers to learn and exchange technology, regularly sharing frontline experience and cutting‑edge topics. We welcome practical discussions and sharing; contact waterystone with any questions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.