实现双锁并发队列

时间:2010-11-16 20:57:52

标签: java concurrency

我正在尝试在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;
    }
}

1 个答案:

答案 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();

我不知道这是否一定是你的测试失败的原因,但它会解决这个并发问题。

编辑:事实证明,对我和我的测试至少,有两个专用锁确实解决了我在队列中看到的奇怪问题。