Nuf*_*ail 16 java concurrency multithreading data-structures
我需要一个线程安全的LIFO结构,并发现我可以使用线程安全的实现Deque.Java 7已经介绍了ConcurrentLinkedDequeJava 6和LinkedBlockingDeque.
如果我只能使用非阻塞的方法LinkedBlockingDeque,例如addFirst()和removeFirst()它有什么区别ConcurrentLinkedDeque?
也就是说,如果你不理会阻塞方面,有没有之间的任何其他差别ConcurrentLinkedDeque和LinkedBlockingDeque,除了LinkedBlockingDeque为界?
Old*_*eon 15
引用伟大的Doug Lea(我的重点)
LinkedBlockingDeque与ConcurrentLinkedDeque
LinkedBlockingDeque类旨在成为"标准"阻塞deque类.当前实现具有相对低的开销但是相对较差的可伸缩性....
... ConcurrentLinkedDeque与LinkedBlockingDeque具有几乎相反的性能配置文件:相对较高的开销,但非常好的可伸缩性....在并发应用程序中,想要一个线程安全但不支持阻塞的Deque并不常见.大多数那些做得更好的可能是特殊情况解决方案.
他似乎建议你应该使用LinkedBlockingDeque除非你特别需要的功能ConcurrentLinkedDeque.
两件事情:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
同样的addFirst方法.在ConcurrentLinkedDeque这种锁定行为中,方法是不同的,并且更有效,因为它不会锁定整个列表而是锁定它的一个子集,检查源代码ConcurrentLinkedDeque将使您更加清楚.
2:来自javadoc ConcurrentLinkedDeque:
请注意,与大多数集合不同,size方法不是恒定时间操作.
..
此外,批量操作addAll,removeAll,retainAll,containsAll,equals和toArray不保证以原子方式执行.
以上不是真的 LinkedBlockingDeque
首先,LinkedBlockingDeque 和 ConcurrentLinkedDeque 都是线程安全的,但使用哪一个取决于您的应用程序要求。
例如,
LinkedBlockingDequeue : 如果您希望一次只有单个线程可以操作您的数据并且您的应用程序需要阻塞,请使用此集合。
ConcurrentLinkedDeque: 这也是线程安全的集合双端队列,如果您的应用程序是多线程的,并且您希望每个线程都可以访问数据,那么 ConcurrentLinkedDequeue 是最好的选择。
正如你的问题中,
1.我需要有一个线程安全的LIFO结构,
如果您希望一次只有单个线程可以操作您的数据,请使用 LinkedBlockingDeque。
如果希望每个线程都可以访问共享数据,请使用 ConcurrentLinkedDeque
2. 如果不考虑阻塞方面,ConcurrentLinkedDeque 和 LinkedBlockingDeque 之间还有其他区别吗?
是的,这是有区别的,因为 LinkedBlockingDeque 使用锁定机制,而 ConcurrentLinkedDeque 则不使用锁定机制,这可能会影响您要操作数据时的性能。