Redis 实现的分布式锁,jedis-2.9.0.jar 以上版本。commons-pool2-2.4.2.jar 以上版本
import java.util.Collections;
import javax.annotation.PostConstruct;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class RedisDistributedLock {
private static volatile JedisPool jedisPool;
private static final String PREFIX = "redis_lock_";
private static final Long RELEASE_SUCCESS = 1L;
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final String RELEASE_LOCK_SCRIPT = "if redis.call(\'get\', KEYS[1]) == ARGV[1] then return redis.call(\'del\', KEYS[1]) else return 0 end";
@PostConstruct
public void initJedis() {loadJedis();
}
private synchronized void loadJedis() {if (jedisPool == null) {
int timeout = 1000 * 30;
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(120);
config.setMaxIdle(50);
config.setMaxWaitMillis(10000);
config.setTestOnBorrow(true);
jedisPool = new JedisPool(config, "127.0.0.1", 6379, timeout, "123456");
}
}
/**
* 返还到连接池
*
* @param pool
* @param redis
*/
public void close(Jedis redis) {if (redis != null) {redis.close();
}
}
/**
* @param lockKey 分布式锁的 key
* @param lockVal 分布式锁得 value
* @param expiredMilliSeconds key 的超时时间
* @param maxWaitMilliSeconds 获取锁的最大超时时间
* @return
*/
public boolean tryLock(String lockKey, String lockVal, long expiredMilliSeconds, long maxWaitMilliSeconds) {long tryLockTime = System.currentTimeMillis();
while (!tryLock(lockKey, lockVal, expiredMilliSeconds)) {if (System.currentTimeMillis() - tryLockTime > maxWaitMilliSeconds) {return false;}
try {Thread.sleep(10L);
} catch (InterruptedException arg9) {}}
return true;
}
private boolean tryLock(String lockKey, String lockVal, long expiredMilliSeconds) {
Jedis jedis = null;
try {jedis = jedisPool.getResource();
String result = jedis.set(PREFIX + lockKey, lockVal, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expiredMilliSeconds);
return LOCK_SUCCESS.equals(result);
} catch (Exception e) { } finally {close(jedis);
}
return false;
}
public boolean unlock(String lockKey, String lockVal) {
Jedis jedis = null;
try {jedis = jedisPool.getResource();
Object result = jedis.eval(RELEASE_LOCK_SCRIPT, Collections.singletonList(lockKey),
Collections.singletonList(lockVal));
return RELEASE_SUCCESS.equals(result);
} catch (Exception e) { } finally {close(jedis);
}
return false;
}
}