在Java中,如果“insert()”和“size()”并发执行,是否存在死锁



代码看起来像这样(链接):

/***
 * Excerpted from "Seven Concurrency Models in Seven Weeks",
***/
import java.util.concurrent.locks.ReentrantLock;
class ConcurrentSortedList {
  private class Node {
    int value;
    Node prev;
    Node next;
    ReentrantLock lock = new ReentrantLock();
    Node() {}
    Node(int value, Node prev, Node next) {
      this.value = value; this.prev = prev; this.next = next;
    }
  }
  private final Node head;
  private final Node tail;
  public ConcurrentSortedList() {
    head = new Node(); tail = new Node();
    head.next = tail; tail.prev = head;
  }
  public void insert(int value) {
    Node current = head;
    current.lock.lock(); 
    Node next = current.next;
    try {
      while (true) {
        next.lock.lock(); 
        try {
          if (next == tail || next.value < value) { 
            Node node = new Node(value, current, next); 
            next.prev = node;
            current.next = node;
            return; 
          }
        } finally { current.lock.unlock(); } 
        current = next;
        next = current.next;
      }
    } finally { next.lock.unlock(); } 
  }
  public int size() {
    Node current = tail;
    int count = 0;
    while (current.prev != head) {
      ReentrantLock lock = current.lock;
      lock.lock();
      try {
        ++count;
        current = current.prev;
      } finally { lock.unlock(); }
    }
    return count;
  }
}

说它使用交接手锁定insert()从列表头到列表尾部锁定,size()从列表尾部锁定到列表头。 size()insert()可以并发执行。

但我认为size()insert()不能并发执行。因为如果insert aNode上锁并请求aNode.next锁,而size aNode.next上锁并请求锁aNode,就会出现死锁。

有人对此有想法吗?谢谢!

我明白了.. size()将在请求新锁之前释放当前锁。所以不会有僵局。

最新更新