我有以下代码用于锁定具有特定用户ID的对象
public boolean acquireLock(Long id) {
if (lock.compareAndSet(0L, id)) {
return true ;
}
return false ;
}
我通过以下方式获得它:
while(!parent.acquireLock(id)){
System.out.println(lock.get());
if (count++>1000000) {
System.out.println(id + " Trying to acquire " + lock.get());
DebugHandler.createException("Error, deadlock");
}
}
将其发布为:
public boolean releaseLock(Long id) {
if (lock.compareAndSet(id, 0)) {
System.out.println("Releasing Lock for " + id);
return true ;
}
else {
DebugHandler.createException("Lock not owned by current view. Thief");
return false ;
}
}
并将锁定对象声明为:
private volatile AtomicLong lo = new AtomicLong(0);
除了我得到以下奇怪的行为和死锁,其结论是:
Id 45试图获得0
Ak,锁的值系统地为0,但是比较和交换测试失败,认为它不是0.(在退出循环后,重新初始化了用于测试死锁的计数器)
有什么想法吗?
答案 0 :(得分:0)
我可以看到您的代码存在问题。如果你得到一个id
为零的线程,你的锁定方案就会崩溃,两个线程最终可能同时持有这个锁。
修复:对您的acquireLock
和releaseLock
方法添加防御性检查,以测试id
是否为非。
关于代码如何进入明显陷入僵局的状态:
这真的是一个真正的僵局。例如,如果某个线程在已经拥有该id
的锁定时尝试获取给定id
的锁定,则可能会发生这种情况。 (您实施的锁是不可重入的。)
您的代码可能无法释放给定id
的锁定;例如因为抛出了异常并且跳过了对releaseLock
的正常调用。