100. 将add()方法的 if(cur.key == key) return false去掉,改为找到 pred.key <= key && curr.key > key为插入的位置。remove()方法和contains()方法都是找到任意一个key == key时结束。
101. 所有的锁都按照升序获得,不会有循环,所以无死锁。
102. 当线程拥有pred.lock和curr.lock的时候,与这2个节点无关的操作并行操作,结果与这个add()方法无关,可以在串行化的历史中任意安排这2个操作的顺序;同时与这2个节点相关的操作,包括在pred后插入节点,删除pred和删除curr都将在获得2个锁的时候串行执行。这是add方法的可线性化点。
103. 没有对获得锁的循环。
104. 只要有pred和curr的关系不断变化就可以。比如说当前节点 head--> ... --> A --> B--> ... --> tail ; Threada想要remove B, Threadb不断在AB之间插入节点:
Ta.pred = A, Ta.curr = B; ==> Tb.pred = A, Tb.curr = B; Tb.pred.lock(), Tb.curr.lock(); ==> Tb inserts A1 ==> A-->A1-->B
==> Ta.pred.lock(), Ta.curr.lock() ==> Ta.validate ==> Ta.pred.next (A.next) != Ta.curr (B) ==> Ta tries remove again.
==> Tb inserts A2 ==> Ta failed ==> ...
或者重复的插入和删除:
Ta.pred = A, Ta.curr = B ==> Tb.pred = A, Tb.curr = B; Tb.pred.lock(), Tb.curr.lock() ==> Tb inserts A1 ==> A-->A1-->B
==> Ta.pred.lock(), Ta.curr.lock() ==> Ta.validate ==> Ta.pred.next != Ta.curr ==> Ta tries remove again.
==> Ta.pred = A1, Ta.curr = B; Tb.pred = A, Tb.curr = A1; Tb.pred.lock, Tb.curr.lock; ==> Tb.remove(curr) ==> A-->B
==> Ta.pred.lock, Ta.curr.lock ==> Ta.validate ==> Ta.pred not reachable ==> Ta tries remove again
==> Repeat
105.
public boolean contains(T item) {
Node last = null, pred = null, curr = null;
int key = item.hashCode();
head.lock();
try {
pred = head;
curr = pred.next;
curr.lock();
try {
while (curr.key < key) {
pred.unlock();
pred = curr;
curr = curr.next;
curr.lock();
}
return (curr.key == key);
} finally {
curr.unlock();
}
} finally