基于Redis实现分布式锁-java工具类
import com.hwqh.huawenstockuser.common.ConstantUtil;import com.hwqh.huawenstockuser.config.MyConfiguration;import com.hwqh.huawenstockuser.entity.model.LinkAccount;import org.slf4j.Logger;import org.s
·
import com.hwqh.huawenstockuser.common.ConstantUtil;
import com.hwqh.huawenstockuser.config.MyConfiguration;
import com.hwqh.huawenstockuser.entity.model.LinkAccount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import redis.clients.jedis.*;
import redis.clients.jedis.exceptions.JedisException;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* JedisPool工具类
* 加载配置文件,配置连接池的参数
* 提供获取连接的方法
*/
public class JedisPoolUtils {
private static final Logger logger = LoggerFactory.getLogger(JedisPoolUtils.class);
public static JedisPool jedisPool;
static {
//获取数据,设置到JedisPoolConfig中
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(MyConfiguration.create().getInt("spring.redis.jedis.pool.max-active"));
config.setMaxIdle(MyConfiguration.create().getInt("spring.redis.jedis.pool.max-idle"));
String string = MyConfiguration.create().getString("spring.redis.password");
if (StringUtils.isEmpty(string)){
jedisPool = new JedisPool(config, MyConfiguration.create().getString("spring.redis.host"), MyConfiguration.create().getInt("spring.redis.port"));
}else{
jedisPool = new JedisPool(config, MyConfiguration.create().getString("spring.redis.host"), MyConfiguration.create().getInt("spring.redis.port"),
MyConfiguration.create().getInt("spring.redis.timeout"),MyConfiguration.create().getString("spring.redis.password"));
}
/**
* 获取分布式锁
*
* @param lockName
* 竞争获取锁key
* @param acquireTimeoutInMS
* 获取锁超时时间
* @param lockTimeoutInMS
* 锁的超时时间
* @return 获取锁标识
*/
public static String acquireLockWithTimeout(String lockName,
long acquireTimeoutInMS, long lockTimeoutInMS) {
Jedis conn = null;
boolean broken = false;
String retIdentifier = null;
try {
conn = jedisPool.getResource();
String identifier = UUID.randomUUID().toString();
String lockKey = "lock:" + lockName;
int lockExpire = (int) (lockTimeoutInMS / 1000);
long end = System.currentTimeMillis() + acquireTimeoutInMS;
while (System.currentTimeMillis() < end) {
if (conn.setnx(lockKey, identifier) == 1) {
conn.expire(lockKey, lockExpire);
retIdentifier = identifier;
return retIdentifier;
}
if (conn.ttl(lockKey) == -1) {
conn.expire(lockKey, lockExpire);
}
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
} catch (JedisException je) {
if (conn != null) {
broken = true;
jedisPool.returnBrokenResource(conn);
}
} finally {
if (conn != null && !broken) {
jedisPool.returnResource(conn);
}
}
return retIdentifier;
}
/**
* 释放锁
* @param lockName 竞争获取锁key
* @param identifier 释放锁标识
* @return
*/
public static boolean releaseLock(String lockName, String identifier) {
Jedis conn = null;
boolean broken = false;
String lockKey = "lock:" + lockName;
boolean retFlag = false;
try {
conn = jedisPool.getResource();
while (true) {
conn.watch(lockKey);
if (identifier.equals(conn.get(lockKey))) {
Transaction trans = conn.multi();
trans.del(lockKey);
List<Object> results = trans.exec();
if (results == null) {
continue;
}
retFlag = true;
}
conn.unwatch();
break;
}
} catch (JedisException je) {
if (conn != null) {
broken = true;
jedisPool.returnBrokenResource(conn);
}
} finally {
if (conn != null && !broken) {
jedisPool.returnResource(conn);
}
}
return retFlag;
}
public static void main(String[] args) {
for(int i = 0 ; i < 20; i ++){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Long s = System.currentTimeMillis();
String key = "K_1000";
String kIdentifier = acquireLockWithTimeout(key,1000L,1000L);
if(kIdentifier == null){
System.err.println("获取锁失败");
return;
} else {
System.err.println("获取锁花费:"+(System.currentTimeMillis() - s));
}
try {
// 模拟业务代码执行块
Thread.sleep(100L);
} catch (Exception e){
e.printStackTrace();
}
System.err.println("执行业务代码(+100):"+ (System.currentTimeMillis()-s));
//释放锁
releaseLock(key,kIdentifier);
System.err.println("End--------------------------------- 释放锁总花费时间:"+(System.currentTimeMillis()-s));
}
});
thread.start();
try {
// 测试并发10毫秒
Thread.sleep(10L);
} catch (Exception e){
e.printStackTrace();
}
}
}
}
更多推荐
所有评论(0)