【发布时间】:2013-10-05 22:50:43
【问题描述】:
我有以下代码用于锁定具有特定用户 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
好吧,锁的值系统地为 0,但比较和交换测试失败,认为它不是 0。(用于测试死锁的计数器在我退出循环后重新初始化)
有什么想法吗?
【问题讨论】:
-
在您的代码中,您在获取锁时使用
this.getWorldID(),但您的日志记录使用this.id。请解决此问题并重新测试,让我们知道结果如何。 -
真的总是0吗?您可以期望它有时为 0。这并不意味着死锁,只是自旋锁被另一个线程持有。
AtomicLong是原子的,但它不是阻塞。 -
你记得在成功时将
count设置为 0 吗? -
是的,它始终为 0,至少对于 1000000 次迭代。而且我确实重置了计数。
-
您正在呼叫
parent.acquireLock(),但正在打印lock.get()。那些是 same 锁吗?parent.lock看起来更像你要找的锁。
标签: java concurrency locking atomic