我尝试使用在LinkList的Node类中初始化的ReentrantLock在Java中实现手动锁定,但我似乎遇到了死锁,我不确定如何修复它。任何帮助将不胜感激。
// Insert value for key.
public boolean add( K key, V value ) {
// Require key != null and value != null
// Get hash code
int hash = key.hashCode();
Node pred = null, curr = null;
try {
pred = head;
pred.lock.lock();
curr = pred.next;
curr.lock.lock();
while( curr.hash <= hash ) {
if( key.equals( curr.key ) ) { // key present, update value
curr.value = value;
return false;
}
pred = curr;
pred.lock.lock();
curr = curr.next;
curr.lock.lock();
}
// key not present
Node node = new Node( hash, key, value );
node.next = pred.next;
pred.next = node;
return true;
} finally {
curr.lock.unlock();
pred.lock.unlock();
}
}
// Remove key/value pair
public boolean remove( K key ) {
// Require key != null
// Get hash code
int hash = key.hashCode();
Node pred = null, curr = null;
try {
// Predecessor node
pred = this.head;
pred.lock.lock();
//Current node
curr = pred.next;
curr.lock.lock();
// traversing list
while( curr.hash <= hash ) {
if( key.equals( curr.key ) ) { // key present, update value
pred.next = curr.next;
return true;
}
pred.lock.unlock();
pred = curr;
curr = curr.next;
curr.lock.lock();
}
// key not found
return false;
}finally {
curr.lock.unlock();
pred.lock.unlock();
}
}
答案 0 :(得分:2)
在add()中的while循环中,实际上有几个问题。
pred
节点未解锁。curr
节点两次。 pred
节点如何解锁?
pred = curr;
pred.lock.lock();
所以在这里,你覆盖了pred
节点的本地引用,现在pred
和curr
都指向同一个节点。因此,在覆盖pred
引用之前,您需要确保将该节点解锁。
curr
节点如何被锁定两次?
pred = curr;
pred.lock.lock();
同样,原因与上述相同。 pred
与此处curr
的节点相同,您已在方法开头锁定curr
。
因此调用pred.lock.lock()
是发生死锁的地方。
应该是:
pred.lock.unlock();
pred = curr;
curr = curr.next;
curr.lock.lock();
答案 1 :(得分:0)
你的while循环有两个锁定语句,它应该是解锁(pred)和锁定(更新当前)。
请通过电子邮件联系您的讲师。