简体   繁体   中英

Implementing two-lock concurrent queue

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 = 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;
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM