I'm trying to implement a two-lock concurrent queue in Java, but I can't get it to pass the automated tests. Please let me know the errors in my code:
private static class Link<L> {
L val;
Link<L> next;
Link(L val) { this.val = val; this.next = null; }
}
T v;
private Link<T> initNode = new Link<T> (v);
private Link<T> first = i开发者_运维百科nitNode;
private Link<T> last = initNode;
public void enque(T val) {
Link<T> newLink = new Link<T> (val);
synchronized (this.last) {
last.next = newLink;
last = newLink;
}
}
public T deque() {
synchronized (this.first) {
Link<T> new_head = first.next;
if (new_head == null)
return null;
T rtnVal = new_head.val;
first = new_head;
return rtnVal;
}
}
The biggest issue here is that you are changing which object is being synchronized on. What ends up happening is really undeterministic.
In your synchronized block you have:
synchronized (this.last) {
last.next = newLink;
last = newLink;
}
Since last is being changed, another thread can enter the enque method and enter the synchronized block at the same time. Your best bet is to have two Objects to block on:
private final Object ENQUEUE_LOCK = new Object();
private final Object DEQUEUE_LOCK = new Object();
I dont know if this is necessarily why your tests are failing, but it would resolve that concurrency issue.
Edit: It turns out, for me and my testing at least, having two dedicated locks does resolve strange issues I saw with the queue.
精彩评论