ConcurrentLinkedDeque与LinkedBlockingDeque的区别

19

我需要一个线程安全的后进先出(LIFO)结构,发现可以使用线程安全的Deque实现。Java 7引入了ConcurrentLinkedDeque,而Java 6有LinkedBlockingDeque

如果我只使用LinkedBlockingDeque中的非阻塞方法,例如addFirst()removeFirst(),它与ConcurrentLinkedDeque有什么区别吗?

也就是说,如果忽略阻塞方面,除了LinkedBlockingDeque是有界的之外,ConcurrentLinkedDequeLinkedBlockingDeque之间还有其他区别吗?


你看过两者的实现了吗?你的标准是什么,你会根据什么来做出选择?性能?内存开销? - Fildor
我只是想知道如果我继续使用Java 6并使用LinkedBlockingDeque会有什么损失。 - Nufail
4个回答

16

引用伟大的Doug Lea的话(我强调)

LinkedBlockingDeque 与 ConcurrentLinkedDeque

LinkedBlockingDeque 类旨在成为“标准”阻塞双端队列类。 当前实现具有相对较低的开销,但相对较差的可扩展性。 ...

... ConcurrentLinkedDeque 具有与 LinkedBlockingDeque 几乎相反的性能特性相对较高的开销,但非常好的可扩展性。... 在并发应用程序中,不太常见需要一个线程安全却不支持阻塞的 Deque。而且,大多数需要的情况可能更适合使用专门解决方案。

他似乎在暗示,除非你需要 ConcurrentLinkedDeque 的功能,否则应该使用 LinkedBlockingDeque


4
请注意,他是在2004年非正式地说的。 - kervin

12

ConcurrentLinkedDeque是无锁的(请参见源代码中的注释),而LinkedBlockingQueue使用锁。因此,前者应该更有效。


9

两件事:

1: 如果我只使用 LinkedBlockingDeque 中的非阻塞方法,比如 addFirst()removeFirst(),与使用 ConcurrentLinkedDeque 是否有任何区别?

这些方法在并发锁定行为方面确实有所不同,在 LinkedBlockingDeque 中:

public E removeFirst() {
        E x = pollFirst();
        ..
    }
 public E pollFirst() {
        lock.lock(); //Common lock for while list
        try {
            return unlinkFirst();
        } finally {
            lock.unlock();
        }
    }

对于 addLast 方法同样适用。在 ConcurrentLinkedDeque 中,这两种方法的锁定行为不同,并且更加高效,因为它不会锁定整个列表,而只是其中的一个子集。查看 ConcurrentLinkedDeque 的源代码可以让您更清楚地了解这一点。

2: 根据 ConcurrentLinkedDeque 的 javadoc:

请注意,与大多数集合不同,size 方法不是常量时间操作。

..

此外,addAll、removeAll、retainAll、containsAll、equals 和 toArray 等批量操作不能保证原子执行。

以上内容不适用于 LinkedBlockingDeque


addAll等操作在LinkedBlockingQueue中也是非原子性的。它使用迭代器来重复获取和释放锁。 - almondandapricot

5

首先,LinkedBlockingDeque和ConcurrentLinkedDeque都是线程安全的,但使用哪一个取决于您的应用需求。

例如:

LinkedBlockingDequeue :如果您希望每次只有单个线程可以操作您的数据,并且需要阻塞应用程序时,请使用此集合。

ConcurrentLinkedDeque: 如果您的应用程序是多线程的,并且您希望每个线程都可以访问数据,则ConcurrentLinkedDequeue是最好的选择。

针对您的问题:

1.我需要一个线程安全的LIFO结构

如果您希望每次只有单个线程可以操作您的数据,请使用LinkedBlockingDeque。

如果您希望每个线程都可以访问共享数据,请使用ConcurrentLinkedDeque。

2.如果忽略阻塞方面,ConcurrentLinkedDeque和LinkedBlockingDeque之间是否存在其他差异?

是的,存在差异。LinkedBlockingDeque使用锁定机制而ConcurrentLinkedDeque则没有这可能会影响您操作数据时的性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接