前言
今天在使用JedisPool的时候,学习到的一些小知识,特地记下来,就当学习了。
setnx
- jedis的setnx是如果不存在,就设置,并返回1,如果要设置的key存在,则不作处理,直接返回0
- setnx有一个缺点就是不能设置过期时间,如果在下面用expire设置过期时间的话,就不能保证其原子性
//这两步不能保证原子性
Long res = jedis.setnx(key, value);//如果成功返回1 失败返回0
Long expire = jedis.expire(key, expired); //设置过期时间
// jedis.expire(key,-1); 设置永不过期
set
由于上面不能保证原子性,所以我们还是用set,我们来看看怎么用
- 让我们先来看看这两个方法是怎么定义的 ,
public String set(String key, String value) {
this.checkIsInMultiOrPipeline();
this.client.set(key, value);
return this.client.getStatusCodeReply();
}
public String set(String key, String value, SetParams params) {
this.checkIsInMultiOrPipeline();
this.client.set(key, value, params);
return this.client.getStatusCodeReply();
}
- 其中有一个很关键的SetParams类
public class SetParams extends Params {
private static final String XX = "xx"; //如果存在 才设置
private static final String NX = "nx"; //如果不存在,设置
private static final String PX = "px"; //设置过期时间 毫秒
private static final String EX = "ex"; //设置过期时间 秒
public SetParams() {
}
public static SetParams setParams() {
return new SetParams();
}
public SetParams ex(int secondsToExpire) {
this.addParam("ex", secondsToExpire);
return this;
}
public SetParams px(long millisecondsToExpire) {
this.addParam("px", millisecondsToExpire);
return this;
}
public SetParams nx() {
this.addParam("nx");
return this;
}
public SetParams xx() {
this.addParam("xx");
return this;
}
public byte[][] getByteParams(byte[]... args) {
ArrayList<byte[]> byteParams = new ArrayList();
byte[][] var3 = args;
int var4 = args.length;
for(int var5 = 0; var5 < var4; ++var5) {
byte[] arg = var3[var5];
byteParams.add(arg);
}
if (this.contains("nx")) {
byteParams.add(SafeEncoder.encode("nx"));
}
if (this.contains("xx")) {
byteParams.add(SafeEncoder.encode("xx"));
}
if (this.contains("ex")) {
byteParams.add(SafeEncoder.encode("ex"));
byteParams.add(Protocol.toByteArray((Integer)this.getParam("ex")));
}
if (this.contains("px")) {
byteParams.add(SafeEncoder.encode("px"));
byteParams.add(Protocol.toByteArray((Long)this.getParam("px")));
}
return (byte[][])byteParams.toArray(new byte[byteParams.size()][]);
}
}
- 可见,nx和xx,ex和px不能同时使用,接下来,我们来看看怎么使用
/**
* 获取锁,失败直接返回
*/
public boolean tryLockFailed(String lock, String value, int expired) {
Jedis jedis = null;
try {
jedis = getJedis();
//如果不存在,才设置,设置过期时间为expired s
String res = jedis.set(lock, value, SetParams.setParams().nx().ex(expired));
return res == null ? false : true;
} finally {
close(jedis);
}
}