Mastering Redis Distributed Locks with Jedis: A Hands‑On Guide

This tutorial demonstrates how to implement Redis distributed locks in Java using Jedis, covering lock creation with SETNX, expiration handling, safe unlocking via Lua scripts, and a high‑concurrency simulation of 100,000 users competing for limited stock.

Programmer DD
Programmer DD
Programmer DD
Mastering Redis Distributed Locks with Jedis: A Hands‑On Guide

This article explains how to implement a Redis distributed lock using Jedis in Java, covering lock creation with SETNX, lock expiration, unlocking via Lua script, and a high‑concurrency simulation of 100,000 users competing for limited stock.

Jedis NX Lock Creation

To create a lock, the code uses jedis.set(key, val, "NX", "PX", timeout), where NX ensures the key is set only if it does not already exist and PX sets the expiration in milliseconds.

public boolean setnx(String key, String val) {
    Jedis jedis = null;
    try {
        jedis = jedisPool.getResource();
        if (jedis == null) {
            return false;
        }
        return jedis.set(key, val, "NX", "PX", 1000 * 60)
                .equalsIgnoreCase("ok");
    } catch (Exception ex) {
    } finally {
        if (jedis != null) {
            jedis.close();
        }
    }
    return false;
}

The parameters NX and PX are explained: NX – set only if the key does not exist; PX – expiration time in milliseconds.

Deleting the Lock

Unlocking is performed by executing a Lua script that deletes the key only when its value matches the owner’s value, ensuring that only the lock holder can release it.

public int delnx(String key, String val) {
    Jedis jedis = null;
    try {
        jedis = jedisPool.getResource();
        if (jedis == null) {
            return 0;
        }
        StringBuilder sbScript = new StringBuilder();
        sbScript.append("if redis.call('get','").append(key).append("')'"
                ).append("=='").append(val).append("' then ")
                .append("return redis.call('del','").append(key).append("') ")
                .append("else return 0 end");
        return Integer.valueOf(jedis.eval(sbScript.toString()).toString());
    } catch (Exception ex) {
    } finally {
        if (jedis != null) {
            jedis.close();
        }
    }
    return 0;
}

Simulating a High‑Concurrency Order Grab

The article creates 100,000 virtual users with IntStream.range(...).parallel(), sets a stock of 10 items, and each user repeatedly tries to acquire the lock within a 30‑second timeout. When a lock is obtained, the stock is decremented, the order is recorded, and the lock is released.

@GetMapping("/qiangdan")
public List<String> qiangdan() {
    List<String> shopUsers = new ArrayList<>();
    List<String> users = new ArrayList<>();
    IntStream.range(0, 100000).parallel().forEach(b -> users.add("User-" + b));
    nKuCuen = 10;
    users.parallelStream().forEach(b -> {
        String shopUser = qiang(b);
        if (!StringUtils.isEmpty(shopUser)) {
            shopUsers.add(shopUser);
        }
    });
    return shopUsers;
}

Logs and screenshots demonstrate that only one request succeeds per lock and that the final list contains the users who successfully purchased the limited stock.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaconcurrencyRedisJedisSpring BootDistributed Lock
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

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.