All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy