英文:
Redis's Redisson's API method .unlock() is not releasing the lock, trying from the same instance
问题
我在我的Java应用程序中创建了一个单例的Redisson实例,我使用它来与Redis服务器进行通信。
现在,使用这个Redisson实例,我正在获取一个锁,在完成一些任务后,我会释放它。但是在调用unlock方法之后,我仍然看到Redis仍然持有该锁,其他线程无法获取该锁。
以下是我正在使用的代码片段:
class RedisInstance
{
static RedisInstance ins;
private RedisInstance()
{
ins = new RedisInstance();
}
public static RedisInstance getInstance()
{
return ins;
}
//获取锁:
public boolean acquireLock(String lockKey)
{
RLock redisLock = getRedisClient().getLock(lockKey);
boolean isLockFree;
try
{
isLockFree = redisLock.tryLock(lockAcquistionTimeLimit, TimeUnit.SECONDS);
if(isLockFree)
{
redisLock.lock();
logger.info("锁已获取:{}", lockKey);
return true;
}
}
catch (InterruptedException e)
{
logger.error("在获取Redis锁时发生异常:{}", e, lockKey);
}
return false;
}
//释放锁:
public void unlock(String lockKey)
{
RLock redisLock = getRedisClient().getLock(lockKey);
redisLock.unlock();
logger.debug("Redis是否已锁定:" + redisLock.isLocked());
logger.info("锁已释放:{}", lockKey);
}
}
class A
{
RedisIns ins = RedisInstance.getInstance();
public void run()
{
if(ins.acquireLock(lockKey))
{
try
{
//进行一些处理,耗时不到一秒
}
catch(Exception e)
{
}
finally
{
ins.unlock(lockKey);
}
}
}
//在我的主方法中:
public static void main(String args[])
{
A a = new A();
A b = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
Thread.sleep(5000); //仅为模拟,假设t1在t2开始之前完成
t2.start();
}
}
在t1调用ins.unlock(lockKey);
之后,日志logger.debug("Redis是否已锁定:" + redisLock.isLocked());
显示为:true,且t2
无法获取锁。
但是,如果我将redisLock.unlock();
替换为redisLock.forceUnlock();
,一切都按预期工作。不知道为什么unlock()无法释放锁,而forceUnlock()可以。
英文:
I have created singleton redisson instance in my Java application, which I am using to communicate to redis servers.
Now using this redisson instance, I am acquiring a lock which after getting some task done, I am releasing. But after calling unlock method, I still see redis have the lock and other threads are unable to acquire the lock.
Below is the code snippet, I am using:
class RedisInstance
{
static RedisInstance ins;
private RedisInstance()
{
ins = new RedisInstance();
}
public static RedisInstance getInstance()
{
return ins;
}
//Acquire the lock:
public boolean acquireLock(String lockKey)
{
RLock redisLock = getRedisClient().getLock(lockKey);
boolean isLockFree;
try
{
isLockFree = redisLock.tryLock(lockAcquistionTimeLimit, TimeUnit.SECONDS);
if(isLockFree)
{
redisLock.lock();
logger.info("lock acquired for: {}", lockKey);
return true;
}
}
catch (InterruptedException e)
{
logger.error("Got exception {} in acquiring Redis Lock for: {}" , e, lockKey);
}
return false;
}
//Release the lock:
public void unlock(String lockKey)
{
RLock redisLock = getRedisClient().getLock(lockKey);
redisLock.unlock();
logger.debug("IS redis locked "+redisLock.isLocked());
logger.info("lock released for: {}", lockKey);
}
}
class A
{
RedisIns ins = RedisInstance.getInstance();
public void run()
{
if(ins.acquireLock(lockKey))
{
try
{
//do some processing takes less than a second
}
catch(Exception e)
{
}
finally
{
ins.unlock(lockKey);
}
}
}
//In my main method:
public static void main(String args[])
{
A a = new A();
A b = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
Thread.sleep(5000); //just to mock, lets say t1 finishes before t2 starts
t2.start();
}
}
After t1 calls ins.unlock(lockKey);
, the log logger.debug("IS redis locked "+redisLock.isLocked());
says: true and t2
is unable to acquire the lock.
But if I replace redisLock.unlock();
with redisLock.forceUnlock();
everything is working as expected.
Dont know why unlock() is unable to release the lock forceUnlock() is able to do it.
答案1
得分: 1
tryLock
如果成功获取了锁,则返回true。因此,在此之后调用lock
是不必要的,我认为这可能是您问题的原因。实现可能期望锁定/解锁成对出现,而在您的情况下,lock
的次数比unlock
多一个。
英文:
tryLock returns true if it acquired the lock. So calling lock after is unnecessary, and I think it may be the cause of your problem. The implementation probably expects an even number of lock/unlock and in you case you have one more lock than unlock.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论