Hashtable 从类名就可以看出是个古老的类,不允许null作为key或者value。加锁的方式保证线程安全,底层使用互斥锁,性能很低,不推荐使用
HashMap是非线程安全的,这意味着不应该在多线程中对这些Map进行修改操作,否则会产生数据不一致的问题,甚至还会因为并发插入元素而导致链表成环。查找的时候造成死循环,影响整个应用程序
Collections工具类可以将一个Map转换成线程安全的实现,是通过一个包装类把所有功能都委托给传入的Map,
包装类是用synchronized关键字保证线程安全的
ConcurrentHashMap底层实现比较复杂,性能也要高上很多。他减小了锁的粒度,没有用一个全局锁锁住自己。而且只有修改、插入的时候才有锁,检索操作是不需要锁的。
LinkedHashMap使用双向链表来维护key-value对的顺序,该链表负责维护Map的迭代顺序,迭代顺序与key-value对的插入顺序保持一致
TreeMap基于红黑树实现。根据其键的自然顺序进行排序,或者根据创建Map时提供的 Comparator 进行排序,具体取决于使用的构造方法。
TreeMap的基本操作containsKey、get、put、remove floorKey,ceilingKey,firstKey方法,它的时间复杂度是log(N)。
TreeMap包含几个重要的成员变量:root、size、comparator
其中root是红黑树的根节点。它是Entry类型,Entry是红黑树的节点,它包含了红黑树的6个基本组成:key、value、left、right、parent和color
略
数组,初始创建容量10,超过限制扩展50%的容量,System.arraycopy() ,优缺点和数组一样。
ArrayList的底层是用数组来实现的,默认第一次插入元素时创建大小为10的数组,超出限制时会增加50%的容量,并且数据以 System.arraycopy() 复制到新的数组,因此最好能给出数组大小的预估值。
按数组下标访问元素的性能很高,这是数组的基本优势。直接在数组末尾加入元素的性能也高,但如果按下标插入、删除元素,则要用 System.arraycopy() 来移动部分受影响的元素,性能就变差了,这是基本劣势。
CopyOnWriteArrayList是Java.util.concurrent包提供的并发类, 读的时候是无锁的,写的时候是会把数据进行一个拷贝,然后再新的数组里写,再把原来的引用指向新数组。这样在写的时候,如果有读的操作,会读之前老副本。因此上锁的写操作不会影响并发的读访问。
因此CopyOnWriteArrayList读性能很高,无需任何同步措施,适用于读多写少的并发场景。
传统的ArrayList在遍历的时候进行修改,会出现ConcurrentModificationException,CopyOnWriteArrayList就不会出现这个问题。
但是缺点也很明显,就是内存占用问题, 每次写都拷贝,数据量大的时候,内存压力大,可能频繁需要GC。
还有个缺点就是无法保证及时性,读的是就的数据,不是强一致性的。
HashSet、TreeSet中的元素都是不能重复的,都是线程不安全的
HashSet 能放null, TreeSet不能
TreeSet能按自然排序或者自定义排序,HashSet无序
HashSet底层是HashMap,value存了一个PRESENT,是静态的Object对象,TreeSet底层是红黑树
抛异常:如果操作无法立即执行,则抛一个异常;
特定值:如果操作无法立即执行,则返回一个特定的值(一般是 true / false)。
阻塞:如果操作无法立即执行,则该方法调用将会发生阻塞,直到能够执行;
超时:如果操作无法立即执行,则该方法调用将会发生阻塞,直到能够执行。但等待时间不会超过给定值,并返回一个特定值以告知该操作是否成功(典型的是true / false)。