并发容器类List、set、queue

List

1、List的基础问题:
ArrayList: 基于数组,因为可以根据数组下标可以直接锁定元素,所以查询效率高;
添加和删除效率较低,因为在进行添加和删除的时候,需要进行元素移位,消耗内存;
初始长度是10;发生扩容时 初始长度*1.5。

LinkedList: 基于链表,因为锁定元素必须是遍历链表全部元素,所以查询效率低;进行删除和添加的时候,由于LinkedList存储元素的数据结构是双向链表结构,由存储元素的结点连接而成,每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可。无初始长度,无扩容机制,在链表上直接进行删除和添加即可。

为什么说List是不安全的集合类
在这里插入图片描述
源代码只要是出现这个size++,就能够说明它存在原子性问题。

那么有没有线程安全的List呢?
答案肯定是有的,看源码:
CopyOnWriteArrayList()机制

在这里插入图片描述
当CopyOnWriteArrayList进行添加的时候,首先加了一把锁,保证了线程安全,然后获取当前数组,然后获取数组的长度,复制旧数组的同时,数组长度加1 变为新数组,然后把将要添加的元素放到数组的尾部,然后把新数组代替旧数组。
这样的CopyOnWriteArrayList其实效率是很低的,因为它在复制数组的时候,是完完全全复制出一个和旧数组一模一样的新数组,它是非常占用内存的,所以它的使用场景也仅仅是在读极多写极少、读极多写极少、读极多写极少的情况。它是数据一致性只能保证最终一致,并不能保证实时一致。

Set

在这里插入图片描述
1、set在意义上是一个数学集合,它是无序的,注意当你的数据很少的时候,jdk会帮你维护顺序,因为有序也是无序中的一种情况,但是当数据量一旦很大,jdk维护起来很吃力的时候,它就不会帮你维护顺序,所以认定set是无序的就可以,它只是有这么一种情况。

然后看它是如何做存储的,看源码:
在这里插入图片描述
是hashmap帮它做的存储,那么是如何用hashmap实现了hashset呢?

hashmap的key值唯一,hashset就是用hashmap的key值作为自己的元素值,然后将hashmap的值舍为object;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、CopyOnWriteArraySet是基于CopyOnWriteArrayList的实现是在添加的时候做了一个判断,判断此元素是否存在,如果存在则不添加,源码如下:
在这里插入图片描述

Queue

在这里插入图片描述
queue是一个接口,我们在这里不做其他解释,主要说一下queue的各种实现类
1、ArrayBlockingQueue
是一个基于循环数组的队列,阻塞是采用Condition线程通讯的方式,进行唤醒挂机线程。在创建对象的时候就固定了数组的长度。
2、LinkedBlockingQueue
基于链表的队列,阻塞队列也是采用Condition线程通讯的方式,进行唤醒挂机线程。
3、SynchronizedQueue
是一个基于数组的队列,无界队列,可以减少队列中节点维护的内存开销;其本身只支持扩容,不支持容量的减少,因为减少容器势必带来数组内容的赋值以及数组对象的回收。其设计的目的就是在最低内存消耗下实现无界容器,对于Tomcat 本身来说,够用就行。在使用场景上,适合使用保存数目的大小比较固定,且不会减少的数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值