以下是锁代码
import com.example.demo.conf.RedisUtil;
import redis.clients.jedis.Jedis;
public class lock {
public static boolean setnx(String key, String val) {
Jedis jedis = null;
try {
jedis = RedisUtil.getJedis();
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;
}
public static int delnx(String key, String val) {
Jedis jedis = null;
try {
jedis = RedisUtil.getJedis();
if (jedis == null) {
return 0;
}
//if redis.call('get','orderkey')=='1111' then return redis.call('del','orderkey') else return 0 end
StringBuilder sbScript = new StringBuilder();
sbScript.append("if redis.call('get','").append(key).append("')").append("=='").append(val).append("'").
append(" then ").
append(" return redis.call('del','").append(key).append("')").
append(" else ").
append(" return 0").
append(" end");
return Integer.valueOf(jedis.eval(sbScript.toString()).toString());
} catch (Exception ex) {
} finally {
if (jedis != null) {
jedis.close();
}
}
return 0;
}
}
下面是抢单代码
import com.example.demo.conf.RedisUtil;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
public class user {
static Jedis jedis = RedisUtil.getJedis();
//获取锁的超时时间 秒
private int timeout = 30 * 1000;
static final String shangpingKey="phone_key";
public void qiangdan() {
//抢到商品的用户
List<String> shopUsers = new ArrayList<>();
//构造很多用户
Vector<String> users = new Vector<>();
IntStream.range(0, 10000).forEach(b -> {
users.add("用户-" + b);
});
//模拟开抢
users.parallelStream().forEach(b -> {
String shopUser = qiang(b);
});
}
/**
* 模拟抢单动作
*
* @param b
* @return
*/
private String qiang(String b) {
//用户开抢时间
long startTime = System.currentTimeMillis();
//未抢到的情况下,30秒内继续获取锁
while ((startTime + timeout) >= System.currentTimeMillis()) {
if (lock.setnx(shangpingKey, b)) {
//用户b拿到锁
// System.out.println("用户"+b+"拿到锁...");
try {
//商品是否剩余
int phone = Integer.parseInt(jedis.get("phone"));
if (phone <= 0) {
break;
}
jedis.incrBy("phone",-1);
String str = b+"抢单成功,所剩库存:" + (phone-1);
System.out.println(str);
} finally {
//释放锁
lock.delnx(shangpingKey, b);
}
} else {
//
}
}
return "";
}
public static void main(String[] args) {
user user = new user();
user.qiangdan();
}
}
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
本文介绍了如何使用Java编写基于Redis的分布式锁机制,用于模拟抢购场景。通过setnx和delnx方法实现锁的获取和释放,同时展示了如何利用Redisson库进行并发控制。
188






