Java:ArrayBlockingQueue与LinkedBlockingQueue

时间:2013-06-12 09:20:26

标签: java multithreading synchronization queue

我认为,在大多数情况下,ArrayBlockingQueue的效果会优于LinkedBlockingQueue。但是,当数组中总有足够的空间时就是这种情况......如果它已经满了,那么它是否会表现得如此之好是不可预测的,因为它会阻塞试图将数据推入队列的线程。

所以,我的问题是:BlockingQueue是否有任何中间实施?比如,ArrayListBlockingQueueBucketListBlockingQueue?类似于数组列表的东西,这样队列可以动态增加容量,同时使用数组最终存储数据仍然有合理的好处吗?

2 个答案:

答案 0 :(得分:14)

1。 LinkedBlockingQueue(LinkedList实现但不完全是LinkedList的JDK实现它使用静态内部类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 )
}

用于维护链接的节点类

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();
}

恕我直言,ArrayBlockingQueue和LinkedBlockingQueue之间最大的区别在于构造函数1具有底层数据结构Array和其他linkedList

ArrayBlockingQueue使用single-lock double condition algorithm而LinkedBlockingQueue是“双锁队列”算法的变体,它有2个锁2条件(takeLock,putLock)

直到现在我对这两个实现进行了比较回到原来的问题,在这个道格Lea谈论有关DynamicArrayBlockingQueue concurrency mailing list

implementation provided by Dawid Kurzyniec.中提出了类似的问题。

答案 1 :(得分:6)

我的2美分:

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

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

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