在Java中控制对集合的多次访问的最不慢的线程安全机制是什么?
我正在将对象添加到一个集合的顶部,但我非常不确定哪种集合会性能最佳。vector还是queue?我最初认为ArrayList很快,但我进行了一些实验,结果非常缓慢。
编辑:在我的插入测试中,使用volatile声明的Vector似乎是最快的?
在Java中控制对集合的多次访问的最不慢的线程安全机制是什么?
我正在将对象添加到一个集合的顶部,但我非常不确定哪种集合会性能最佳。vector还是queue?我最初认为ArrayList很快,但我进行了一些实验,结果非常缓慢。
编辑:在我的插入测试中,使用volatile声明的Vector似乎是最快的?
最好的算法尽可能避免共享状态。听起来你对Java的多线程编程还很陌生。为什么不选择一些你知道肯定正确的东西...然后看看有多少同步,再看看是否有问题...然后看看是否能找到更快的方法。
确切的操作应该决定使用什么。然而,由于容器在很大程度上是一种抽象类型,因此编写它使其可靠工作,然后进行剖析,确保功能要求,根据需要进行优化等等 :)
通常,我主要使用"并发集合"是用于在线程之间传输对象的队列。在这种情况下,我从ConcurrentLinkedQueue开始,原因是喜欢“无锁”算法(但这并不意味着它会更快:-)。
一般来说,队列和/或链表是一个很好的数据结构,可以将内容附加到末尾。根据情况,包括特定的使用模式,例如线程争用、删除的项目数量、如何删除项目等等,除了开始/结束之外,“快速杀死”所有项目可能会更快地通过清除(AbstractQueue的一部分)和重新添加项目来完成——ConcurrentLinkedQueue允许同时检查/操作头部和尾部。然而,我建议“保持简单”,写入“特定接口合同”,并“仅使用当前方法”,直到有强有力的证据表明未满足功能需求为止。h.putIfAbsent(k,v)
(来自ConcurrentHashMap)与if (!h.containsKey(k)) { h.put(k, v); }
不同--举个例子,像“清除然后添加”方法中提到的问题也适用于这种情况。
编码愉快。
嗯,如果我正确理解了“使用volatile的向量”这个评论,您可能并不完全理解同步的含义。Volatile只适用于对Vector的引用;而由于Vector本身是同步的,因此它将是多余的。
但从根本上讲,您真的认为由于同步(用于容器访问)而导致的性能差异足以让您担心吗?如果是这样,您应该能够通过分析(访问和/或变异的热点)看到效果。我并不是说没有这种情况发生,但它们并不特别常见。
ConcurrentSkipListMap/Set - 但你必须知道如何/何时使用它。CopyOnWriteArrayList是另一个很好的解决方案(同样需要知道为什么要使用它)。
编辑:在我的插入测试中,使用volatile声明的Vector似乎是最快的?
那只是不酷而且完全没有用。