Backend Development 11 min read

Understanding Redisson Distributed Lock Implementation in Java

This article explains how Redisson leverages Redis, Lua scripts, and Pub/Sub to implement a robust distributed lock in Java, covering lock characteristics, client creation, acquisition, renewal, and release mechanisms with code examples.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding Redisson Distributed Lock Implementation in Java

Introduction: Locks are used to control concurrent access to shared resources; in single‑service environments Java's synchronized or Lock implementations suffice, but in distributed systems they are inadequate, leading to the need for distributed locks.

Common distributed lock implementations include MySQL row‑level pessimistic lock, Redis (setnx+expire), and Zookeeper; this article focuses on Redis‑based Redisson and explains why it is recommended.

Characteristics of Distributed Locks

Mutual exclusion across threads and services, with considerations for spinning vs blocking.

Timeout to avoid stale locks.

Lease renewal (watchdog) because the exact execution time is unknown.

Re‑entrancy allowing the same thread to acquire the lock multiple times.

Ownership‑only release to prevent accidental unlocks.

Fair vs non‑fair acquisition policies.

Redisson implementation details:

Client creation

Each Redisson client generates a unique UUID used as an identifier in the lock metadata.

Lock acquisition

The lock method attempts to acquire the lock, subscribes to a Redis channel if it fails, and blocks until a release notification is received. The core steps are:

Try to acquire the lock (Lua script) and set lease time.

Subscribe to the lock channel using Redis Pub/Sub.

Cancel the subscription once the lock is obtained or the attempt is abandoned.

Key code snippets:

@Before
public void before() {
    Config config = new Config();
    config.useSingleServer()
            .setAddress("redis://192.168.1.110:6379");
    redissonClient = Redisson.create(config);
}
@Test
public void multiLock() throws Exception {
    RLock testLock = redissonClient.getLock("multi_lock");
    int count = 5;
    CountDownLatch latch = new CountDownLatch(count);
    for (int i=1; i<=count; i++) {
        new Thread(() -> {
            try {
                System.out.println("Thread " + Thread.currentThread().getName() + " trying to acquire lock");
                testLock.lock();
                System.out.println(String.format("Thread %s acquired lock, executing business...", Thread.currentThread().getName()));
                TimeUnit.SECONDS.sleep(5);
                System.out.println(String.format("Thread %s business done", Thread.currentThread().getName()));
                latch.countDown();
            } finally {
                testLock.unlock();
                System.out.println(String.format("Thread %s released lock", Thread.currentThread().getName()));
            }
        }, "t" + i).start();
    }
    latch.await();
    System.out.println("Finished");
}

Lock release

Unlocking runs a Lua script that decrements the re‑entrancy counter, removes the lock when the counter reaches zero, and publishes a release message to the channel.

Summary

Redisson achieves mutual exclusion, timeout, lease renewal, re‑entrancy, ownership‑only release, and supports fair/non‑fair policies by using Redis hash structures, Lua scripts, and Pub/Sub mechanisms.

backendJavaConcurrencyRedisDistributed LockRedisson
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.