同步容器类和并发容器类

匿名 (未验证) 提交于 2019-12-03 00:27:02

1、同步容器类

包括Vector(实现了一个动态数组,和ArrayList相似,但两者是不同的)和Hashtable。

同步容器类的问题:

例如:Vector的getLast方法,和deleteLast方法,都会执行“先检查,后执行”操作,每个方法首先都获得数组的大小,然后通过结果来获取或删除最后一个元素。如果线程A调用getLast,线程B调用deleteLast,在线程A调用size和getLast之间,线程B删除了一个元素,则getLast会出现数组越界异常。同样,这种风险在对Vector中的元素进行迭代时仍然会出现。

解决方法:在客户端,将每个方法都进行加锁,使得每次只能有一个线程访问容器。

缺点:这样的话,同步容器类将所有对容器状态的访问都串行化,以实现它们的线程安全性,代价是严重降低并发性。

(1)Hashtable

链表+数组实现,初始容量11,扩容因子0.75。每一次扩容,为上一次容量的2倍+1.

源码:
















// 将“key-value”添加到Hashtable中





































































(2)Vector

数组实现,初始容量10。Vector 当扩容容量增量大于0时、新数组长度为原数组长度+扩容容量增量、否则新数组长度为原数组长度的2倍。与ArrayList不同的就是两方面,分别是是否线程安全和扩容机制。

2、并发容器类(针对多个线程并发访问设计的)

包括ConcurrentHashMap、CopyOnWriteArrayList

(1)ConcurrentHashMap

并不是在每个方法上都加锁,使得每次只能有一个线程访问容器,而是使用分段锁。

ConcurrentHashMap的实现中使用了一个包含16个锁的数组,每个锁保护散列桶的1/16,其中第N个散列桶由第(Nmod16)个锁来保护,正是这项技术使得ConcurrentHashMap能够支持多达16个并发的写入器。

锁分段的劣势:当需要加锁整个容器的时候,单个锁来实现独占访问只需要获得一个锁,ConcurrentHashMap需要获得16个锁,增加了复杂度。

ConcurrentHashMap源码解析:

ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同部分进行的修改。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

采用二次哈希的方法:第一次定位到哪一个segment,第二次定位到具体的桶。

进行读操作时,不需要加锁:首先判断count(该segment桶的数量)是否为0,若为0,则返回null,否则,根据hash值和key找到相应的value,判断value是否为null,若为null,则利用加锁的方式再次去获取(防止在此期间新增了一个entry,另一个线程新增的这个entry又恰好是我们要get的,因为这个entry可能只构造了一半),否则返回该值(即要查找的值)。

注:count和value都是volatile类型,所以假设有线程增加或删除一个entry,count的新值都是对所有线程可见的;如果get过程中,另一个线程改变了该value值,对于该线程来说也是可见的。若在此期间删除(next是不可变的,所以需要重新复制一份链表以实现相应的删除操作)了要查找的entry,而get查找的仍然是旧链表,所以仍然会找到value并返回。

进行增加、删除、修改操作时都需要加锁。

在容器的size()操作时,需要依次加锁整个容器,然后再按顺序释放各个锁,一定要按顺序,否则可能会造成死锁.

(2)CopyOnWriteArrayList

当修改(包括更新、添加、删除)CopyOnWriteArrayList时,需要加锁(可重入锁),先从原有的数组中拷贝一份出来,然后在新的数组做写操作,写完之后,将原来数组的引用指向新数组。

在进行读操作的时候,如果写操作尚未完成,则读的是旧容器中的数据。所以,多个线程可以同时对这个容器进行迭代,而不会彼此干扰或者与修改线程的容器相互干扰。

缺点:(1)内存占用问题:每当修改容器时,都会复制底层数组,需要占用内存。

CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果你希望写入的的数据,马上能读到,请不要使用CopyOnWrite容器。


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!