Search code examples
javajava.util.concurrent

Why doesn't LinkedBlockingQueue use LinkedList internally?


When reading the source code of LinkedBlockingQueue, I notice that it uses a linked list with ReentrantLock. But since Java already has an implementation called LinkedList, why isn't it used in LinkedBlockingQueue directly? Similarly, linked list is implemented again in LinkedBlockingDeque.

public class LinkedBlockingDeque<E> extends AbstractQueue<E>
    implements BlockingDeque<E>, java.io.Serializable {

    private LinkedList<E> queue;
    final ReentrantLock lock = new ReentrantLock();

    // take the remove(Object) method as example
    public boolean remove(Object o) {
        if (o == null) return false;
        fullyLock();
        try {
            queue.remove(o);
            return false;
        } finally {
            fullyUnlock();
        }
    }

    // ... the rest of the class
}

What isn't it implemented like the code above? What's the trade-off behind this?


Solution

  • Here are some reasons that a private linked list class is used:

    1. The linked list used in LinkedBlockingQueue is a singly linked list. LinkedList is doubly linked. This uses more memory, and has a small performance penalty. (This doesn't apply in the LinkedBlockingDeque case.)

    2. LinkedList provides fail-fast iterators, and uses a modCount field to detect concurrent modification. This must be incremented on each list operation that modifies the list. That is a small performance penalty compared with LinkedBlockingQueue and LinkedBlockingDeque which provide weakly consistent iterators, and don't have a modCount.

    3. LinkedBlockingQueue and LinkedBlockingDeque are by design weakly consistent. If they were to use LinkedList under the hood, the latter's fail-fast behavior could not be hidden ... as @Holger pointed out.