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