多线程-- 六.并发容器 J.U.C

J.U.C 

是JDK提供的一个包名的缩写,全名为:java.util.concurrent

如图:

 

 

 

1.ArrayList --> CopyOnWriteArrayList

    相比于ArrayList,它是线程安全的。

    当有新元素添加到CopyOnWriteArrayList容器中时,它先从原有数组中拷贝一份出来,在新的数组中做写操作,写完之后将原来的数组指向到新的数组。它的整个Add操作都是在锁的保护下进行的。读的操作是不需要加锁的,写操作是加锁的。

    缺点:写操作时需要复制数组,消耗内存。如果元素内容过多,可能会导致Full gc。不能用于实时读的场景。

    适用场景:读多写少。

    设计思想:读写分离;最终一致性;使用时另外开辟空间,通过这种方式解决掉并发冲突。

 

 

2.HashSet --> CopyOnWriteArraySet        TreeSet --> ConcurrentSkipListSet

    CopyOnWriteArraySet是基于CopyOnWriteArrayList的,适用场景跟CopyOnWriteArrayList基本一样。

    ConcurrentSkipListSet是基于Map集合的,在多线程环境下他的contains,remove,add都是线程安全的。但是批量操作的那些,例如containsAll,removeAll,addAll这些,不保证是线程安全的。它不能有空元素。

 

 

3.HashMap --> ConcurrentHashMap        TreeMap--> ConcurrentSkipListMap

(重点)

一.Hashmap

1.Hashmap的数据结构:

    HashMap的底层就是一个数组结构,而数组中的每一项又是一个链表结构;

    当我们新建一个HashMap的时候,就会初始化一个数组出来。

    HashMap有两个参数影响它的性能,一个是初始容量(默认是16),一个是加载因子(默认是0.75)

        容量是哈希表中桶的数量。初始容量只是哈希表在创建时的容量;

        加载因子是哈希表在容量自动增加之前,可以达到多满的一个尺度。如果达到了加载因子的值 ,那么会调用resize方法进行扩容。将容量进行翻倍。

        这两个值在初始化时构造函数是可以自定义的。

 

2.Hashmap的寻址方式:

    对于一个新插入的数据,或者我们需要读取的数据。Hashmap会对它的key按照一定的计算规则计算出的哈希值并对数组长度进行取模。结果作为它数组中的index。但是在计算机中取模的代价比较大,所以Hashmap要求数组的长度必须为2的N次方,此时呢它将key的哈希值对2的N-1次方进行与运算,结果与取模相同的。

    Hashmap并不要求用户在初始化的时候指定容量必须传入的N次方的整数,而是在初始化时根据传入的参数计算出一个满足的容量值。源码中的tableSizeFor方法即可看到。

    

    总所周知,Hashmap的线程不安全,其实主要体现在刚才的resize方法可能会出现死循环,以及使用迭代器会出现FastFail。

    当Hashmap得size超过容量乘加载因子的时候,就会进行扩容。就是创建了一个新的长度为原容量2倍的数组。并将原数组全部重新插入到现数组中,这个方法我们成为rehash。这个方法不保证线程安全,并且在多线程环境下可能会出现死循环。

 

二.ConcurrentHashMap

1.ConcurrentHashMap的数据结构:

    如图:线程安全的

 

也是数组+链表结构,但是最外层不像HashMap直接是个大的数组,而是Segment数组,每个Segment里面是跟HashMap结构差不多的链表数组

Java7之前是分段锁。Java8之后在链表长度超过一定长度之后(默认是8),链表转化为了红黑树。提高并发性。

 

三.ConcurrentSkipListMap

    ConcurrentSkipListMap的效率一般没有ConcurrentHashMap高,但是也有优点。

    1.可以保证有序性

    2.并发数越大,越能体现优势。

        

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值