ConcurrentLinkedDeque与LinkedBlockingDeque
我需要一个线程安全的LIFO结构,并发现我可以使用Deque
线程安全实现。 Java 7引入了ConcurrentLinkedDeque
,Java 6引入了LinkedBlockingDeque
。
如果我只使用addFirst()
的非阻塞方法,例如addFirst()
和removeFirst()
,它与ConcurrentLinkedDeque
有什么区别吗?
即如果你忽略阻塞方面,除了LinkedBlockingDeque
有界之外, ConcurrentLinkedDeque
和LinkedBlockingDeque
之间是否还有其他区别?
两件事情:
1:如果我只使用addFirst()
的非阻塞方法,例如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(); } }
同样适用于addFirst
方法。 在ConcurrentLinkedDeque
这个方法的锁定行为是不同的,并且更有效,因为它不会锁定整个列表而是锁定它的一个子集,检查ConcurrentLinkedDeque
源代码将使您更加清楚。
2:来自ConcurrentLinkedDeque
javadoc:
请注意,与大多数集合不同,size方法不是恒定时间操作。
..
此外,批量操作addAll,removeAll,retainAll,containsAll,equals和toArray不保证以primefaces方式执行。
对于LinkedBlockingDeque
上面的描述不正确
引用伟大的Doug Lea (我的重点)
LinkedBlockingDeque与ConcurrentLinkedDeque
LinkedBlockingDeque类旨在成为“标准”阻塞deque类。 当前实现具有相对低的开销但是相对较差的可伸缩性 。 …
… ConcurrentLinkedDeque与LinkedBlockingDeque具有几乎相反的性能配置文件 : 相对较高的开销,但非常好的可伸缩性 。 …在并发应用程序中,想要一个线程安全但不支持阻塞的Deque并不常见。 大多数那些做得更好的可能是特殊情况解决方案。
他似乎建议你应该使用LinkedBlockingDeque
除非你特别需要ConcurrentLinkedDeque
的function。
ConcuredntLinkedDequeue是无锁的(请参阅源代码中的注释),而LinkedBlockingQueue使用锁定。 那是前者应该更有效率
LinkedBlockingDeque和ConcurrentLinkedDeque都是线程安全的,但使用哪一个取决于您的应用程序要求。
例如,
LinkedBlockingDequeue:如果您希望一次只有单个线程可以对您的数据进行操作以及何时需要阻止您的应用程序,请使用此集合。
ConcurrentLinkedDeque:这也是线程安全的集合deque,如果你的应用程序是multithreading的,并且你希望你的每个线程都可以访问数据,那么ConcurrentLinkedDequeue是最好的选择。
在你的问题中,
1.我需要一个线程安全的LIFO结构,
如果您希望只有单个线程可以操作您的数据,请使用LinkedBlockingDeque。
如果您希望每个线程都可以访问共享数据,请使用ConcurrentLinkedDeque
2.如果忽略阻塞方面,ConcurrentLinkedDeque和LinkedBlockingDeque之间是否还有其他区别,
是的,因为LinkedBlockingDeque使用锁定机制并且ConcurrentLinkedDeque不是这样可能会影响您想要操作数据时的性能。