Implementing Redis Distributed Lock with Jedis and Simulating High‑Concurrency Order抢单
This article explains how to use Jedis to create and delete a Redis distributed lock, demonstrates a setNX‑based locking strategy with expiration, and simulates a 100,000‑user concurrent order‑抢单 scenario to show lock acquisition, order processing, and release in Java.
The article introduces Redis distributed locks, a common interview topic, and uses a simulated order‑抢单 scenario to illustrate the implementation.
Dependency
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>Lock creation with setNX
Jedis' set method is called with the NX option (set only if the key does not exist) and PX for a millisecond expiration, ensuring that only one client can acquire the lock at a time.
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) {
// handle exception
} finally {
if (jedis != null) jedis.close();
}
return false;
}The method returns true only when the lock is successfully set; otherwise it returns false.
Lock deletion
A Lua script is used to delete the lock atomically only when the stored value matches the requester’s value.
public int delnx(String key, String val) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
if (jedis == null) return 0;
StringBuilder sb = new StringBuilder();
sb.append("if redis.call('get','").append(key).append("')=='").append(val).append("' then ")
.append("return redis.call('del','").append(key).append("') else return 0 end");
return Integer.valueOf(jedis.eval(sb.toString()).toString());
} catch (Exception ex) {
// handle exception
} finally {
if (jedis != null) jedis.close();
}
return 0;
}The delete API simply forwards the request to the above method.
Simulating 100,000 concurrent users
Using Java parallel streams, 100,000 virtual users are created, a product inventory of 10 is initialized, and each user repeatedly attempts to acquire the lock within a 30‑second timeout. When a lock is obtained, the user sleeps for one second to mimic order processing, decrements the inventory, and finally releases the lock.
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 "";
}The key points of the implementation are:
parallelStream() simulates many users competing for the same product.
The loop (startTime + timeout) >= System.currentTimeMillis() lets a failed user keep trying within the timeout.
Inventory is checked before and after acquiring the lock. jedisCom.setnx(shangpingKey, b) obtains the lock.
After a successful order, the lock is released with jedisCom.delnx(shangpingKey, b).
Log screenshots show that only one request succeeds per lock acquisition and that the lock expires automatically, fulfilling the distributed‑lock requirements.
Finally, the API returns the list of users who successfully placed an order.
---
Follow the public account "Java派" for more Java backend tutorials.
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.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.
