我正在学习Java集合框架(不是并发集合框架),我了解到有些collection实现是线程安全的,而有些则不是。
在我所读到的大多数材料中,提到xyz是线程安全的,而abc不是线程安全的。
但是根据什么逻辑来决定是否保持给定的集合类型(例如,列表、集合、队列,甚至在Map中)。)线程安全吗?
我的问题是关于“传统”收集框架,而不是关于并发收集框架。
理解这一点的任何投入都将有很大帮助。
发布于 2017-12-17 12:58:40
线程安全带来了开销(尽管在现代VM中,开销比设计集合框架时要低得多)。因此,集合不是线程安全的,除非它是特别需要的,除了JDK1.1集合--当它们被设计时,其理念更像是“让我们为错误留出很少的空间,而代价是一些性能”。
我们在Java的演化中有几个阶段。
JDK1.1
在Java1.1版本中,我们使用了数据结构Vector和Hashtable。它们是完全同步的,提供了一个级别的线程安全。
JDK1.2
在Java版本1.2中,引入了集合框架。没有一个基本集合是线程安全的(它们不同步任何操作):ArrayList、LinkedList、HashMap、TreeMap和Set实现。
但是您可以通过调用Collections.synchronizedMap、Collections.synchronizedList等来获得同步版本。
JDK1.5
在Java1.5版本中,引入了java.util.concurrent框架。它们包含用于多线程使用的专用数据。这些都提供了一个级别的线程安全。
请注意,即使使用同步集合,也可以引入数据竞赛;这只意味着不能破坏集合的内部结构(集合的所有不变量都将被维护)。
例如,如果您有一个两步进程,首先检查集合是否包含某些元素,然后在第二步中插入该元素。如果没有为这两个步骤提供自己的同步,则如果两个线程同时执行此操作,则可以将元素添加两次。
发布于 2017-12-17 13:14:10
正如其他人所述,并发集合具有运行时和潜在的内存开销,因此在线程安全集合和不安全集合中分离。
在单线程库中可以找到的大多数数据结构都有几种线程安全的替代方案。一个值得注意的例外是List,这可能是因为应用程序中很少需要并发列表。
对于诸如队列和堆栈之类的东西,您有大量的选择,因为一个生产者和一个或几个消费者同时拉和推队列是很常见的事情。要实现缓存,您可以依赖于一个映射,这就是为什么并发映射也很受支持的原因。
某些数据结构在线程安全API中没有得到真正的镜像,这仅仅是因为它们在多线程上下文中通常不会有用。
发布于 2017-12-17 12:59:12
原因很可能与性能有关。多个线程之间的同步是一项昂贵的操作,特别是使用大量的元素集合。
https://stackoverflow.com/questions/47855270
复制相似问题