Java中个容器的对比

 List: 有序,列表存储,元素可重复

Set: 无序,元素不可重复

Map:无序,元素可重复,key不能重复

LinkedList :链表,删除和添加效率很高,随机访问效率较ArrayList类低,允许null。


ArrayList:线性表,随机访问效率类高,添加和删除 效率很低,允许null。


HashSet: Set 类元素不可重复 HashSet利用Hash函数进行了查询效率上的优化,允许null。

 

HashMap: 提供了key-value的键值,非synchronized比较快,Hash散列机制查找方便,允许null键值和值。

 

HashTable:容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下HashTable的效率非常低下。

        Hashtable对get,put,remove都使用了同步操作,它的同步级别是正对Hashtable来进行同步的,

       也就是说如果有线程正在遍历集合,其他的线程就暂时不能使用该集合了,这样无疑就很容易对性能和吞吐量造成影响,从而形成单点。

 

ConcurrentHashMap:只对put,remove操作使用了同步操作,get操作并不影响;

      HashTable在竞争激烈的并发环境下表现效率低下,是因为所有访问HashTable的线程都必须竞争同一把锁

      那假如容器里有多把锁,每把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,

      从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术

      首先将数据分成一段一段的存储,然后给每一段数据配一把锁,

      当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。有些方法需要跨段,比如 size()和 containsValue(),

      它们可能需要锁定整个表而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。这里“按顺序”是很重要的,

      否则极有可能出现死锁,在ConcurrentHashMap内部,段数组是final的,并且其成员变量实际上也是final的,

      但是,仅仅是将数组声明为final的并不保证数组成员也是final的,这需要实现上的保证。这可以确保不会出现死锁,因为获得锁的顺序是固定的。

 

TreeSet:使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

    add,remove等基本操作log(n)的时间开销。

参照的原文地址:https://www.cnblogs.com/xuxinstyle/p/11326346.html

posted @ 2019-10-14 19:41  NOT_COPY  阅读(269)  评论(0编辑  收藏  举报