我正在尝试在Java中实现双锁并发队列,但我不能让它通过自动化测试。请告诉我代码中的错误:
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 = initNode;
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;
}
}
答案 0 :(得分:3)
这里最大的问题是你正在改变正在同步的对象。最终发生的事情真是不确定。
在您的同步块中,您有:
synchronized (this.last) {
last.next = newLink;
last = newLink;
}
自上次更改后,另一个线程可以进入enque方法并同时进入synchronized块。最好的办法是让两个对象阻止:
private final Object ENQUEUE_LOCK = new Object();
private final Object DEQUEUE_LOCK = new Object();
我不知道这是否一定是你的测试失败的原因,但它会解决这个并发问题。
编辑:事实证明,对我和我的测试至少,有两个专用锁确实解决了我在队列中看到的奇怪问题。