java中的常用集合和线程安全

来源:互联网 发布:mac拷贝视频到iphone 编辑:程序博客网 时间:2024/05/23 21:55
java中的常用集合和线程安全
早在jdk的1.1版本中所以的集合都是线程安全的,但是在1.2以及之后的版本中就出现了一些线程不安全的集合,为什么版本神级以及会出现一些线程不安全的集合呢,以为线程安全的集合普遍比线程不安全的集合效率高的多,随着业务的发展,特别是在web应用中,为了提高用户体验减少用户的等待时间,页面响应速度(也就是效率)是优先考虑的。而且对线程不安全的集合加锁以后也能达到安全的效果(但是效率会低,因为会有锁的获取以及等待),其实在jdk源码中相同效果的集合线程安全的比线程不安全的就多了一个同步机制,但是效率上却低了不止一点点,因为效率低,所以已经不太建议使用了。
下面举一些常用的功能相同却线程安全和不安全的集合

Vector:就比Arraylist多了个同步化机制(线程安全)

LinkedList:因为成员方法大多是synchronized的,因此LinkedList是线程安全的而ArrayList不是线程安全的

Hashtable:就比Hashmap多了个线程安全

顺带提一些 StringBuffer是线程安全,而StringBuilder是线程不安全的

线程安全的类其方法是同步的,每次只能一个访问。是重量级对象,效率较低。

Vector的方法都是同步的(synchronized),所以是线程安全的,二Arraylist的方法不是,由于线程安全的同步机制必
然回影响性能,因此ArrayList的性能比Vector要好。在扩容机制上当Vector的元素超过它的初始化大小的时候会将容
量翻倍,而ArrayList只会增长50%的大小,这样Vector就白白的浪费了大量的空间。

LinkList和ArrayList在数据结构上市有较大的差别的 ArrayList的数据结构是基于数组的(Object[]),而LinkList内部结构是基于一组链接的记录,形式上属于链表的。因为是链表所以不存在扩容(一下子容量翻盘)之说,所以在增加元素方面linkList效率会高,但是如果加在末尾就没啥区别(不扩容的情况下),因为如果向ArrayList中添加(前面或者中间)的时候再其后面的元素需要整体向后移(类似元素重新排列),但是如果linkList添加一个元素 无论是加在前面和后面原理都是一样的(添加一个Entry的性能,ArrayList则需要重新排序),删除类似,查询的时候如果是随机获取某一个元素ArrayList性能要好些。反正LinkList增加,删除性能好线程安全,ArrayList随机读取效率高,线程不安全。如果是迭代读取其性能没啥差别。

hashtable是线程安全的,即hashtable的方法都提供了同步机制;hashmap不是线程安全的,即不提供同步机制 ;hashtable不允许插入空值,hashmap允许!里面的数据结构和操作方式基本一致。

ConcurrentHashMap:是一种高效但是线程安全的集合
ConcurrentHashMap和HashMap相比是线程安全的,但是效率也比较高。以为它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。在ConcurrentHashMap中,就是把Map分成了N个Segment(数组元素),put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中:因为HashMap的数据结构是数据和链表,通过hash算法算错该key所以在的数组下标,然后在根据equals去比较可以的值然后在获取对象。通俗的说就是ConcurrentHashMap是对每个数组进行加锁,也就是说当多个线程同时访问的该集合的时候,通过hash算法得出的结果相同的时候才需要去同步数据(等待或获取锁),这样能碰见锁的概览就大大大大大大的减少了,因为为了分布均匀,HashMap为了防止hash重复,引入了高位算法,所以这样经过计算以后的值能落在同一个数组上的几率又大大的减少了。HashMap的这些算法和操作全部继承与AbstractMap抽象类,二ConcurrentHashMap也继承了AbstractMap抽象类,所以也继承了这些操作也具备这些功能。当然效率高也是相对HsahTable的。通过这样的机制效率比HsahTable高了很多很多,而且又是线程安全的
0 1
原创粉丝点击