【Java并发解析】并发容器解析

并发容器概览

常用的并发容器

在这里插入图片描述

重点的主要是ConcurrentHashMap , CopyOnWriteArrayList, 和接口BlockingQueue

淘汰的并发容器

  • Vector:性能不好,主要是全部都是synchronized保护起来的方法,并发性不好。
  • Hashtable: 线程安全的hashmap,同时是性能不好,sychronized修饰。
  • Collections.synchronizedList(new ArrayList<E>())Collections.synchronizedMap(new HashMap<K, V>()): 把synchronized加在了代码块上。

锁的粒度太大。

ConcurrentHashMap

我们首先从HashMap的源码开始分析,map在Java里面是一个很大的家族体系。
在这里插入图片描述

  • 常用的家族:
    HashMap: 朴实无华的字典结构
    LinkedHashMap: 可以保留插入的顺序,可以按照顺序查找。
    TreeMap: 实现了排序接口,可以按照key的顺序进行一定的处理。

  • 为什么Hashmap是线程不安全的:

    1. 同时put碰撞导致数据丢失。
    2. 同时扩容导致数据调式
    3. 可能导致死循环。

HashMap

采用拉链法处理哈希碰撞,在1.8中,当拉链法的长度到达一定的程度时候(默认为8),会变成红黑树。用BST可以提高查找的速度,用红黑树可以自动平衡节点的防止极端不平衡影响查找的效率。默认负载因此0.75。

  • 为什么要采用红黑树的形式
    默认是链表因为链表需要的存储空间小,并且在8以上才需要转换,这种概率极低,千万分之几。保证在极端情况下可以保证查询速度。

ConcurrentHashMap

源码解析

在这里插入图片描述

采用多个segment的思路,每个segment都有一个独立的ReentrantLock锁,彼此互不影响,提高了并发效率。默认是16个的segment,初始化之后不可以扩容。

第一次添加元素的时候,默认初期长度为16,当往map中继续添加元素的时候,通过hash值跟数组长度取与来决定放在数组的哪个位置,如果出现放在同一个位置的时候,优先以链表的形式存放,在同一个位置的个数又达到了8个以上,如果数组的长度还小于64的时候,则会扩容数组。如果数组的长度大于等于64了的话,在会将该节点的链表转换成树。在扩容完成之后,如果某个节点的是树,同时现在该节点的个数又小于等于6个了,则会将该树转为链表。

在任何一个构造方法中,都没有对存储Map元素Node的table变量进行初始化。而是在第一次put操作的时候在进行初始化。

在1.8中,采用的是类似与HashMap的方法,并且是分为了很多个node,因此每一个节点都具有并发性。并且使用了CAS的方法。

在这里插入图片描述

核心方法
源码解析
putVal这个方法在增长链表或者给红黑树加节点这个环节还是用了synchronized。

在这里插入图片描述在这里插入图片描述

还可以使用一些线程安全的方法如map.replace(key, oldval, newval)这个可以实现类似于CAS的操作,返回一个布尔逻辑值告诉我们操作是否如愿。map.putIfAbsent(key, val)如果当前key不存在,就放入,否则取出。

并发队列

并发队列概述

  • 为什么使用:可以在线程之间传递数据;不用操心安全性
  • 线程安全的队列:
  • 在这里插入图片描述

阻塞队列BlockingQueue

  • put,take:会阻塞
  • add,remove,element:如果无法实现,会返回异常
  • offer, poll, peekL:如果失败会返回布尔值。

源码分析:LinkedBlockingQueue分别使用了putLock和takeLock,利用singnal进行通信。

非阻塞队列ConcurrentLinkedQueue

采用了CAS的方法实现并发的线程安全。

CopyOnWriteArrayList

  • 构造:CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>(new Integer[]{1, 2, 3});

  • 适用场景:读操作尽可能的快,即使写慢一些也无所谓。读多写少。

  • 读写规则:**只有写写之间存在互斥。**实际上是修改了备份。因此存在一个小的问题,在迭代中修改的东西没法立刻体现。迭代器能的得到的数据,取决于创建的时间,而不是迭代的时间。

  • 原理:创建了新的副本,读写分离的思想。

  • 缺点:数据一致性存在问题;内存占用问题。

源码分析
使用了Reentrantlock进行add方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值