发布
社区首页 >问答首页 >ArrayLists与向量比较

ArrayLists与向量比较
EN

Stack Overflow用户
提问于 2020-09-25 16:53:32
回答 2查看 58关注 0票数 1

在一个赋值问题中,有人问当有多个线程访问和修改it.If时,使用and ArrayList是否合适,而不是问什么是最好的方法

我知道ArrayLists是不同步的,所以这意味着在性能方面,使用ArrayLists是个不错的选择

但由于多线程修改和访问它,我认为数据的完整性可能不安全,所以从这个角度来看,我认为在考虑数据完整性时向量更合适,因为向量是同步的。

我想知道我的建议是否correct.Or ArrayLists在上述情况下是最好的

EN

回答 2

Stack Overflow用户

发布于 2020-09-25 17:03:51

如果你使用的是Vector,它在同步时总会有一些开销。ArrayList不是那么安全,但是对于你的线程,你可以自己做同步,例如使用同步的对象或者:

代码语言:javascript
代码运行次数:0
复制
Collections.synchronizedList(new ArrayList<String>());

然后,您仍然可以在线程任务完成后访问ArrayList,而不会产生向量的开销。如果你只在线程中使用列表,我想Vector也是一个很好的选择。我尽量避免使用Vector。

票数 1
EN

Stack Overflow用户

发布于 2020-09-28 09:53:33

我只有英特尔的线程构建块和微软的并行模式库中的concurrent_vector的经验,但我认为它们可能可以与Java的Vector相媲美。

从我的测试来看,两者中的concurrent_vector都比大多数替代方案慢得多,比如执行多个线程并在本地线程不安全的容器(如C++中的std::vector )中收集结果,然后将结果附加到锁中的共享集合中,或者创建一个列表列表,每个线程写入自己的列表(使用一些数组索引),然后以串行方式在结束时将结果组合到一个列表中。

据我所知,线程安全版本的好处是方便。我从来没有发现过并发的、线程安全的随机访问序列,即使是在Intel自己的库中,我也无法用线程不安全的替代方案来击败它。在线程不安全的替代方案中,我在一个线程中本地累积结果,然后使用一些基本的线程同步,并在一个线程中以串行方式组合结果。如果我的测试是写繁重的,那么我通常可以用这种粗糙的方法比并发容器快2-3倍的结果。

也就是说,在许多情况下,您的时间实际上偏向于向容器写入/附加元素,这种情况可能很少见。更多的时候,我发现我在现实世界中的大部分线程案例都花在了阅读和处理数字之类的事情上,只有一小部分时间花在了将结果推到容器的后面。因此,通常情况下,并发容器的开销开始变得可以忽略不计,而且它肯定要方便得多,而且跨线程误用的可能性也要小得多。

在可能很少见的情况下,写入容器是并行算法中花费的大量时间,在我的测试和经验中,并发容器从未为原始替代方案提供性能优势。因此,如果这是一个特别关键的代码部分,并且您在性能分析会话中看到并发容器方法中的热点,我会尝试在非并发的线程本地容器(即线程本地ArrayList)中累积输出,然后在算法结束时(例如:组合ArrayList)以串行方式从一个线程或在锁/临界区中组合它们的所有结果。

不幸的是,让它既是线程安全的,又是可伸缩的,这是很棘手的。只需在一个线程中执行所有操作,就可以在架构中最大限度地实现线程安全。线程安全问题解决了!但这根本不能扩展到利用并行性的优势。我发现了这样的并发性--一种与Amdahl定律正面相撞的平衡行为。我发现并发容器处于中等水平,因为使用它们几乎总是在某种程度上牺牲最佳性能,但最佳和非最佳之间的差异可能可以忽略不计。好的,你测量一下,就像我看到的那样。

至于你问题的这一部分:

,但由于多线程修改和访问它,我认为数据的完整性可能不安全

从我的角度来看,这是与设计相关的。我从理论角度思考计算机科学已经有很长一段时间了,但在这个概念中有一个隐含的假设,即这些数据必须共享。根据用户端需求,数据可能需要共享,也可能不需要共享。以从scene访问数据的视频游戏为例。看起来渲染引擎和物理引擎等等都必须共享同一个场景。这是很有道理的。这对人类来说是有意义的。

然而,情况并不一定是这样。从用户端的角度来看,如果渲染器有自己的场景副本,用于将结果渲染到屏幕上,这可能并不重要,这可能与正在进行的其他事情略有不同步。因此,通常情况下,至少在需要最佳性能或帧率或最小等待时间的情况下,您可以复制/复制数据,以允许线程尽可能快地运行,而不需要访问共享数据所需的任何线程同步(包括排除原子操作)。这可以通过持久化数据结构和类似的东西变得非常复杂。这取决于设计。但我认为多线程编程的一个违反直觉的方面是,我们首先倾向于认为需要在线程之间共享的东西比它们真正需要共享的东西更多,而抛弃这种假设可能会产生全新的并行性。我和我的许多同事和我自己发现,拥有触手可及的并发容器会诱使我们在线程之间共享比实际需要更多的数据。如果我们的目标是尽可能有效地利用硬件,那么尽可能多地放弃共享数据的概念通常是有意义的,包括这些并发容器。实际上,如果你的软件像游戏引擎一样对性能至关重要,我会建议尽量减少它们的使用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64060907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档