All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.logicbus.redis.util.RedisLock Maven / Gradle / Ivy
package com.logicbus.redis.util;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.anysoft.util.KeyGen;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import com.logicbus.redis.client.Client;
import com.logicbus.redis.context.RedisPool;
import com.logicbus.redis.context.RedisSource;
import com.logicbus.redis.params.SetParams;
import com.logicbus.redis.toolkit.ScriptTool;
import com.logicbus.redis.toolkit.StringTool;
/**
* 基于redis的lock实现
* @author yyduan
*
* @since 1.6.9.9
*
* @version 1.6.9.9 [20170829 duanyy]
* - 增加基于redis的分布式锁实现
*/
public class RedisLock implements Lock {
/**
* a logger of log4j
*/
private static Logger LOG = LoggerFactory.getLogger(RedisLock.class);
protected String redisKey;
protected String redisValue;
protected int interval = 1000;
protected int lockTTL = 30000;
protected String poolId = "default";
protected static final String unlockScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end";
protected boolean locked = false;
public RedisLock(String lockname,Properties props){
redisKey = String.format("%s$%s", PropertiesConstants.getString(props, "table", "lock"),lockname);
redisValue = String.format("%d%s", System.currentTimeMillis(),KeyGen.uuid(5,0,9));
poolId = PropertiesConstants.getString(props, "pool", poolId);
lockTTL = PropertiesConstants.getInt(props, "ttl", lockTTL);
interval = PropertiesConstants.getInt(props,"interval",interval);
}
@Override
public void lock() {
try {
lockInterruptibly();
} catch (InterruptedException e) {
LOG.error("Lock waiting thread has been interrupted,exit",e);
}
}
@Override
public void lockInterruptibly() throws InterruptedException {
while (!tryLock(0,TimeUnit.MILLISECONDS)){
Thread.sleep(interval);
}
}
@Override
public Condition newCondition() {
return null;
}
@Override
public boolean tryLock() {
RedisPool pool = RedisSource.get().get(poolId);
if (pool == null){
throw new RedisContextException("core.e1003","Can not find redis pool:" + poolId);
}
Client client = pool.getClient();
try {
StringTool tool = (StringTool) client.getToolKit(StringTool.class);
redisValue = String.format("%d%s", System.currentTimeMillis(),KeyGen.uuid(5,0,9));
SetParams sp = new SetParams();
sp.ttl(lockTTL, TimeUnit.MILLISECONDS);
sp.onlySet(true);
locked = tool.set(redisKey, redisValue,sp);
return locked;
}finally{
pool.recycle(client, false);
}
}
@Override
public boolean tryLock(long timeout, TimeUnit tu)
throws InterruptedException {
return tryLock();
}
@Override
public void unlock() {
if (locked){
RedisPool pool = RedisSource.get().get(poolId);
if (pool == null){
throw new RedisContextException("core.e1003","Can not find redis pool:" + poolId);
}
Client client = pool.getClient();
try {
ScriptTool tool = (ScriptTool) client.getToolKit(ScriptTool.class);
tool.eval(unlockScript, 1, redisKey,redisValue);
tool.getIntegerReply();
}finally{
pool.recycle(client, false);
}
}
}
}