标签:产生 ted remove 区别 linked lin 链表 volatile 一个
- List
ArrayList
LinkedList
Vector
Stack
CopyOnWriteArrayList
- Set
HashSet
TreeSet
LinkedHashSet
ConcurrentSkipListSet
- Map
HashMap
LinkedHashMap
ConcurrentHashMap
HashTable
TreeMap
ConcurrentSkipListMap
- Queue
ConcurrentLinkedQueue
LinkedBlockingQueue
ArrarBlocakingQueue
PriorityQueue
List、Set 是,Map 不是。Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素(数学中的集合也是如此),List是线性结构的容器,适用于按数值索引访问元素的情形。
Collection是一个接口,它是Set、List等容器的父接口;
Collections是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。
- ArrayList
底层:数组
- Vector
底层:数组
Vector是线程安全的容器,性能上较ArrayList差
- Stack
底层:Vector
- LinkedList
底层:双向链表
从JDK1.7开始,LinkedList 由双向循环链表改为双向链表
- CopyOnWriteArrayList
原理:写复制
在很多应用场景中,读操作都远远多于写操作,对于这些场景,我们希望其读操作尽可能快,即使写操作慢一些也没关系。而因为读操作不会对数据进行修改,所以产生了读写锁,其读与读之间不会阻塞,但是读与写、写与写之间还是会阻塞。而CopyOnWriteArrayList进一步优化,将读取性能发挥到了极致,这个容器读与读之间不会阻塞,读与写之间也不会阻塞,只有写与写之间需要同步等待,这样读操作性能得到了提升
其原理就是写复制,当这个List需要修改时,并不改变原有内容,而是将原有数据进行复制出一个副本,对副本内容进行修改,修改完成后用修改后的副本替换原有数据。这样就保证写操作不会影响读操作了,而且其内部数组使用了volatile修饰,读取线程可以立即察觉到这个修改。
存在问题
1.内存占用问题:因进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象。如果这些对象占用的内存比较大,那么这个时候很有可能造成频繁的 GC。
数据一致性问题:CopyOnWrite 容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果希望写入的的数据马上能读到,就不要使用此容器。
- ArrayList和LinkedListed都是非线程安全的,可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强实现)
- HashSet
底层使用HashMap,遇到hashcode相同的元素不会直接拉链,而是使用equals进行比对,确认不重复再进行插入
元素是无序的add(),remove(),contains()方法的时间复杂度是O(1)
- TreeSet
底层使用TreeMap,TreeMap是底层是红黑树
它里面的元素是有序的,add(),remove(),contains()方法的时间复杂度是O(logn)
- LinkedHashSet
继承自HashSet,内部使用LinkedHashMap
- ConcurrentSkipListSet
底层使用ConcurrentSkipListMap,跳表,输出有序
HashMap
以前有写过
HashTable
HashTable和HashMap内部原理相同,Hashtable使用了synchronized关键字,是线程安全的,而HashMap不是线程安全的
HashMap允许K/V都为null HashMapK/V都不允许为null
TreeMap
红黑树
LinkedHashMap
继承自HashMap,每个节点变为双向链表,可以实现按照插入顺序输出元素
ConcurrentHashMap
HashMap不是线程安全的,基于减小锁粒度的原理,我们将HashMap内部分为16段分别加锁,相互之间不需要同步,从而提升其吞吐量
ConcurrentSkipListMap
原理: 跳表,对内部Node所有操作都时基于CAS
- ConcurrentLinkedQueue
基于CAS
- BlockingQueue
- 内部使用生产者消费者模式,当有线程来取数据时,若队列为空,则将其休眠,有数据时将其唤醒。
- LinkedBlockingQueue
-内部使用链表的阻塞队列,适合做无界队列,内部元素可以动态增加,不会因为初始值很大,而占据很大的内存
- ArrarBlockingQueue
- 内部使用队列,适合做有界队列,存取快,但是在创建时需要指定队列大小,提前创建好队列。创建完成后大小不能调整。类似循环链表,有takeIndex和putIndex两个指针,每次从putIndex处存,从takeIndex处取。
- PriorityQueue
-优先队列,使用小顶堆实现,保证根节点为最小元素,每次存取后需要重新调整堆
List元素以线性方式存储,集合中可以存放重复对象
Set集合中的对象不按特定的方式排序,并且没有重复对象
Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小的,而ArrayList大小是固定的
标签:产生 ted remove 区别 linked lin 链表 volatile 一个
原文地址:https://www.cnblogs.com/INnoVationv2/p/13169390.html