Mastering Redis Distributed Locks with Jedis: A Step-by-Step Guide
This article demonstrates how to implement a Redis distributed lock using Jedis in Java, explains lock creation and deletion strategies, and walks through a simulated high‑concurrency order‑grabbing scenario with 100,000 users to illustrate practical usage.
This article explains how to implement a Redis distributed lock using Jedis in Java, suitable for interview scenarios, and demonstrates a simulated high‑concurrency order‑grabbing case.
Jedis NX Lock Creation
It describes the lock strategy, expiration handling, and provides the Maven dependency needed.
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>The setnx method uses the NX and PX options to ensure only one client acquires the lock and to set an automatic expiration.
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;
}Lock Deletion
To safely release a lock, the same value must be provided; a Lua script performs an atomic check‑and‑delete.
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 100k Concurrent Orders
The example initializes a small stock, creates 100,000 virtual users, and uses parallel streams to mimic a flash‑sale scenario where each user repeatedly tries to acquire the lock within a timeout.
// total stock
private long nKuCuen = 0;
private String shangpingKey = "computer_key";
private int timeout = 30 * 1000;
@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("神牛-" + b);
});
nKuCuen = 10;
users.parallelStream().forEach(b -> {
String shopUser = qiang(b);
if (!StringUtils.isEmpty(shopUser)) {
shopUsers.add(shopUser);
}
});
return shopUsers;
} private String qiang(String b) {
long startTime = System.currentTimeMillis();
while ((startTime + timeout) >= System.currentTimeMillis()) {
if (nKuCuen <= 0) break;
if (jedisCom.setnx(shangpingKey, b)) {
try {
if (nKuCuen <= 0) break;
TimeUnit.SECONDS.sleep(1);
nKuCuen -= 1;
return b + "抢单成功,所剩库存:" + nKuCuen;
} finally {
jedisCom.delnx(shangpingKey, b);
}
}
}
return "";
}Images below show a successful lock acquisition, the execution log, and the final list of users who obtained the order.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
