在Java中,insert()和size()并发执行会不会死锁?
In Java, is there a deadlock if `insert()` and `size()` executed in concurrency?
代码如下所示 (link):
/***
* 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
的锁并请求 [= =19=],会出现死锁。
有人对此有想法吗?谢谢!
我明白了.. size()
会在请求新锁之前释放当前锁..所以不会有死锁..
代码如下所示 (link):
/***
* 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
的锁并请求 [= =19=],会出现死锁。
有人对此有想法吗?谢谢!
我明白了.. size()
会在请求新锁之前释放当前锁..所以不会有死锁..