提交 fa8873e4 authored 作者: 许俊's avatar 许俊

微调

上级 391b9226
package org.jeecg.common.util;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.stereotype.Repository;
import java.nio.charset.Charset;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Repository
public class RedisLock {
/**
* 解锁脚本,原子操作
*/
private static final String unlockScript =
"if redis.call(\"get\",KEYS[1]) == ARGV[1]\n"
+ "then\n"
+ " return redis.call(\"del\",KEYS[1])\n"
+ "else\n"
+ " return 0\n"
+ "end";
private StringRedisTemplate redisTemplate;
public RedisLock(StringRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 加锁,有阻塞
* @param name
* @param expire
* @param timeout
* @return
*/
public String lock(String name, long expire, long timeout){
long startTime = System.currentTimeMillis();
String token;
do{
token = tryLock(name, expire);
if(token == null) {
if((System.currentTimeMillis()-startTime) > (timeout-50))
break;
try {
Thread.sleep(50); //try 50 per sec
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
}while(token==null);
return token;
}
/**
* 加锁,无阻塞
* @param name
* @param expire
* @return
*/
public String tryLock(String name, long expire) {
String token = UUID.randomUUID().toString();
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisConnection conn = factory.getConnection();
try{
Boolean result = conn.set(name.getBytes(Charset.forName("UTF-8")), token.getBytes(Charset.forName("UTF-8")),
Expiration.from(expire, TimeUnit.MILLISECONDS), RedisStringCommands.SetOption.SET_IF_ABSENT);
if(result!=null && result)
return token;
}finally {
RedisConnectionUtils.releaseConnection(conn, factory);
}
return null;
}
/**
* 解锁
* @param name
* @param token
* @return
*/
public boolean unlock(String name, String token) {
byte[][] keysAndArgs = new byte[2][];
keysAndArgs[0] = name.getBytes(Charset.forName("UTF-8"));
keysAndArgs[1] = token.getBytes(Charset.forName("UTF-8"));
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisConnection conn = factory.getConnection();
try {
Long result = (Long)conn.scriptingCommands().eval(unlockScript.getBytes(Charset.forName("UTF-8")), ReturnType.INTEGER, 1, keysAndArgs);
if(result!=null && result>0)
return true;
}finally {
RedisConnectionUtils.releaseConnection(conn, factory);
}
return false;
}
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论