是否有不同步的Java堆栈的替代品?

是否有不同步的Java堆栈的替代品?,java,data-structures,stack,Java,Data Structures,Stack,我有一个使用堆栈数据结构的大型代码库(由我编写)。这是为了方便起见,我有时将其用作堆栈,有时用作向量/列表 然而,在性能审查之后,我们决定不为同步安全性支付额外费用。我现在需要用一个非同步的结构替换这个结构(代码中多次提到) 我很高兴地发现Apache集合中包含了一个与我想要的完全相同的(与Java堆栈相同,但不同步)。但是,它没有像现代Java5代码那样的泛型(这就是我所使用的)。我不会把我的代码转换成Java 1.4 那么,是否有其他兼容Java5的drop-in替代Java堆栈,或者我需要

我有一个使用堆栈数据结构的大型代码库(由我编写)。这是为了方便起见,我有时将其用作堆栈,有时用作向量/列表

然而,在性能审查之后,我们决定不为同步安全性支付额外费用。我现在需要用一个非同步的结构替换这个结构(代码中多次提到)

我很高兴地发现Apache集合中包含了一个与我想要的完全相同的(与Java堆栈相同,但不同步)。但是,它没有像现代Java5代码那样的泛型(这就是我所使用的)。我不会把我的代码转换成Java 1.4

那么,是否有其他兼容Java5的drop-in替代Java堆栈,或者我需要自己编写

更新:

我使用LinkedList和调优的“pop”/“push”方法。

当你说“符合Java 5”时,直到Java 6才出现,但听起来像是你想要的(当然,在适当的情况下使用
Deque
接口)。您可以在需要时将其用作堆栈,或者用作更合适的队列。。。基本上只需调用适当的方法。

在您的特殊情况下(实际上仅在这种情况下),我只需将Stack类从开源Java SE实现复制并粘贴到您自己的包中,并删除所有同步的关键字。您可能需要添加
扩展java.util.Stack
。现在您只需更改代码中的导入声明

我确实意识到,复制代码通常不是一个好主意,但以下是为什么这不适用于这种情况:

  • 如果堆栈的
    pop()
    push()
    语义非常适合当前代码,那么这不会因为性能考虑而改变。deque或链表的语义不同(它们允许从两侧添加/删除)
  • java.util.Stack
    的同步开销不能通过子类化(调用
    super
    方法)或委托等其他技术来消除
  • 最好是复制经过良好测试的代码(只要许可证允许),而不是从头重写

一般来说,最好像使用接口一样使用
java.util.Stack
,而不是在代码中使用
new Stack()
,而是使用工厂对其进行实例化。

正如Jon Skeet所说,ArrayDeque是一个不错的选择。顺便说一句,ArrayStack与Stack的意义相同,因为ArrayStack继承自ArrayList,这是一个很好的继承用法示例;-)。顺便说一句,如果您使用的是现代的HotSpot JVM,很有可能它已经为您优化了锁。例如,它已经使从
StringBuffer
(同步)到
StringBuilder
(非同步)的转换基本上不必要(尽管它仍然有它的位置)。@Adam是的,我知道,但尝试向客户解释一下@kazanaki:很公平。顺便问一下,谁进行了你现在必须遵守的“绩效评估”?咨询公司?你知道他们是否衡量了现有应用程序的性能以指导他们的建议吗?@Adam审查是由客户执行的。不要问……在Java 5.0中,您可以使用
LinkedList
add(0,E)
进行推送,使用
remove(0)
进行弹出。@Peter:我同意。依靠一个具体的类型是很遗憾的(@Peter我可能会照你说的做。如果你愿意,把你的评论作为回答,这样我就可以接受了!否则Jon Skeet爵士会得到所有荣誉!@Peter:我考虑过提到LinkedList,但怀疑OP想要(部分)基于数组的解决方案的缓存一致性。但是,LinkedList也可以使用。@kazanaki,您可以使用List作为接口,因为它可以处理任何列表。但是,要使ArrayList有效工作,您必须从末尾添加/删除。(这比使用LinkedList更快,但更丑陋)
add(e)
用于推送和
remove(List.size()-1)
对于pop,必须尊重版权。一般来说,复制代码是一个坏主意,尤其是从Oracle:)复制代码,而且它是一个“堆栈”,任何人都应该能够从头开始编写。@unreputable:这就是为什么我明确地说“从开源Java SE实现”(我指的是Apache Harmony)。当然,尊重许可证仍然是必要的,但如果你这样做,你可以复制它。