Java: ArrayBlockingQueue vs. LinkedBlockingQueue

我认为,在大多数情况下,将比.但是,当数组中始终有足够的空间时,情况就是如此...如果它满了,它是否会表现得那么好就不是很可预测,因为它会阻止试图将数据推送到队列中的线程......ArrayBlockingQueueLinkedBlockingQueue

所以,我的问题是:是否有任何中间地带的实施?比如说,一个还是一个?类似于数组列表,以便队列可以动态增加容量,同时仍然从使用数组最终存储数据中获得合理的好处?BlockingQueueArrayListBlockingQueueBucketListBlockingQueue


答案 1

1 . (实现但不完全是 JDK 实现。它用于维护元素之间的链接)LinkedBlockingQueueLinkedListLinkedListstatic inner class Node

Constructor for LinkedBlockingQueue
public LinkedBlockingQueue(int capacity) 
{
        if (capacity < = 0) throw new IllegalArgumentException();
        this.capacity = capacity;
        last = head = new Node< E >(null);   // Maintains a underlying linkedlist. ( Use when size is not known )
}

Node用于维护链接的类

static class Node<E> {
    E item;
    Node<E> next;
    Node(E x) { item = x; }
}

2 . ( 阵列实现 )ArrayBlockingQueue

的构造函数ArrayBlockingQueue

public ArrayBlockingQueue(int capacity, boolean fair) 
{
            if (capacity < = 0)
                throw new IllegalArgumentException();
            this.items = new Object[capacity]; // Maintains a underlying array
            lock = new ReentrantLock(fair);
            notEmpty = lock.newCondition();
            notFull =  lock.newCondition();
}

和 之间的最大区别从构造函数中可以明显看出,一个具有 的基础数据结构,而另一个具有 。ArrayBlockingQueueLinkedBlockingQueueArrayLinkedList

ArrayBlockingQueue使用单锁双条件算法,是“双锁队列”算法的变体,它有2个锁2个条件(takeLock,putLock)LinkedBlockingQueue

到目前为止,我对这两个实现进行了比较 回到原始问题,在这个doug Lea谈论的DynamicArrayBlockingQueue的并发邮件列表中也提出了类似的问题,这是Dawid Kurzyniec提供的实现。


答案 2

我的2美分:

首先,这里的底线是你并不真正关心这里的差异,因为即使你使用普通的LinkedBlockingQueue,当你提供一些微秒级系统时,性能也足够好。因此,这里的性能差异并不是那么大。

如果您正在编写任务关键型高性能系统,并且使用队列在线程之间传递消息,则始终可以通过 [队列大小] = [最大可接受延迟] * [最大消息速率] 来估计所需的队列大小。任何可以增长到超出这种容量的东西都意味着你会遇到一个缓慢的消费者问题。在关键任务应用程序中,这种延迟意味着您的系统出现故障。可能需要一些手动过程来确保系统正常运行。

如果您的系统不是关键任务,您可以简单地暂停(阻止)发布者,直到某些使用者可用。


推荐