Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数组列表与向量比较_Java_Collections - Fatal编程技术网

Java 数组列表与向量比较

Java 数组列表与向量比较,java,collections,Java,Collections,在一个作业问题中,有人问,当有多个线程访问和修改ArrayList时,使用和ArrayList是否合适。如果不是,那么最好的方法是什么 我知道ArrayList是不同步的,因此从性能角度来看,使用ArrayList是一个不错的选择 但是由于多线程修改和访问它,我认为数据的完整性可能不会得到保护,因此从这个角度来看,我认为向量在考虑数据完整性时更合适,因为向量是同步的 我想知道我的建议是否正确,或者ArrayList是否是上述场景中最好的 .如果您使用Vector,它将始终有一些用于同步的开销。A

在一个作业问题中,有人问,当有多个线程访问和修改ArrayList时,使用和ArrayList是否合适。如果不是,那么最好的方法是什么

我知道ArrayList是不同步的,因此从性能角度来看,使用ArrayList是一个不错的选择

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

我想知道我的建议是否正确,或者ArrayList是否是上述场景中最好的


.

如果您使用Vector,它将始终有一些用于同步的开销。ArrayList并不那么安全,但对于线程,您可以自己进行同步,例如使用同步对象或:

Collections.synchronizedList(new ArrayList<String>());
Collections.synchronizedList(新的ArrayList());

然后,您仍然可以在执行线程任务后访问ArrayList,而无需Vector的开销。如果您只是在线程中使用列表,我想Vector也是一个不错的选择。我尽量避免使用向量。

我只对英特尔的线程构建块和微软的并行模式库中的
concurrent\u Vector
之类的东西有经验,但我认为它们可能与Java的
Vector
相当

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

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

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

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

不幸的是,要使事情既具有线程安全性,又具有最大的可扩展性,这是很棘手的。您只需在一个线程中执行所有操作,就可以在体系结构中最大限度地保证线程安全。线程安全问题解决了!但这并不是为了利用并行性而进行扩展。我发现这种并行性——一种与阿姆达尔定律相抵触的平衡行为。我发现并发容器处于中等位置,因为使用它们几乎总是在某种程度上牺牲最佳性能,但最佳和非最佳之间的差异可能可以忽略不计。好吧,你测量并看到我所看到的

关于你问题的这一部分:

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

从我的角度来看,这与设计有关。自从我从理论角度思考计算机科学以来,已经有好几年了,但是这里有一个隐含的假设,即这些数据必须共享。根据用户终端要求,数据可能需要共享,也可能不需要共享。拍摄一个视频游戏,从
场景访问数据。看起来渲染引擎和物理引擎等必须共享同一场景。这是很直观的。这是有道理的

但事实并非如此。从用户端的角度来看,如果渲染器有自己的场景副本,用于将结果渲染到屏幕上,而该副本可能与正在进行的其他事情稍微不同步,则这一点可能并不重要。因此,通常情况下,至少在需要最佳性能或帧速率或最小等待时间的情况下,您可以复制/复制数据,以允许线程尽可能快地运行,而无需访问共享数据所需的任何线程同步(包括排除原子操作)。无论是否使用持久数据结构等,这都会变得非常复杂。这取决于设计。但我认为多线程编程的一个反直觉的方面是,我们首先倾向于认为线程之间需要共享的东西比它们真正需要共享的东西更多,而放弃这个假设可以产生全新的并行度。我已经发现了很多