JAVA并发容器有哪些

  介绍

这篇文章主要介绍“JAVA并发容器有哪些”,在日常操作中,相信很多人在JAVA并发容器有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答“JAVA并发容器有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

<强> ConcurrentHashMap并发版HashMap

最常见的并发容器之一,可以用作并发场景下的缓存。底层依然是哈希表,但在JAVA 8中有了不小的改变,而JAVA 7和JAVA 8都是用的比较多的版本,因此经常会将这两个版本的实现方式做一些比较(比如面试中)。

一个比较大的差异就是,JAVA 7中采用分段锁来减少锁的竞争,JAVA 8中放弃了分段锁,采用CAS(一种乐观锁),同时为了防止哈希冲突严重时退化成链表(冲突时会在该位置生成一个链表、哈希值相同的对象就链在一起),会在链表长度达到阈值(8)后转换成红黑树(比起链表,树的查询效率更稳定)。

<强> CopyOnWriteArrayList并发版ArrayList

并发版ArrayList,底层结构也是数组,和ArrayList不同之处在于:当新增和删除元素时会创建一个新的数组,在新的数组中增加或者排除指定对象,最后用新增数组替换原来的数组。

适用场景:由于读操作不加锁,写(增、删、改)操作加锁,因此适用于读多写少的场景。

局限:由于读的时候不会加锁(读的效率高,就和普通ArrayList一样),读取的当前副本,因此可能读取到脏数据。如果介意,建议不用。

看看源码感受下:

 public  class  CopyOnWriteArrayList
  ,,,implements  List,, RandomAccess,,可克隆,,java.io.Serializable  {
  ,,,final  transient  ReentrantLock  lock =, new  ReentrantLock ();
  ,,,private  transient  volatile 对象[],数组;
  
  ,,,//,添加元素,有锁
  ,,,public  boolean 添加(E  e), {
  ,,,,,,,final  ReentrantLock  lock =, this.lock;
  ,,,,,,,lock.lock();,//,修改时加锁,保证并发安全
  ,,,,,,,try  {
  ,,,,,,,,,,,对象[],elements =, getArray();,//,当前数组
  ,,,,,,,,,,,int  len =, elements.length;
  ,,,,,,,,,,,对象[],newElements =, Arrays.copyOf(元素,len  +, 1),,//,创建一个新数组,比老的大一个空间
  ,,,,,,,,,,,newElements (len),=, e,,//,要添加的元素放进新数组
  ,,,,,,,,,,,setArray (newElements);,//,用新数组替换原来的数组
  ,,,,,,,,,,,return 真实;
  ,,,,,,,},{finally 
  ,,,,,,,,,,,lock.unlock();,//,解锁
  ,,,,,,,}
  ,,,}
  
  ,,,//,读元素,不加锁,因此可能读取到旧数据
  ,,,public  E 得到(int 指数),{
  ,,,,,,,return 得到(getArray(),指数);
  ,,,}
  }
<强> CopyOnWriteArraySet并发组

基于CopyOnWriteArrayList实现(内含一个CopyOnWriteArrayList成员变量),也就是说底层是一个数组,意味着每次添加都要遍历整个集合才能知道是否存在,不存在时需要插入(加锁)。

适用场景:在CopyOnWriteArrayList适用场景下加一个,集合别太大(全部遍历伤不起)。

<强> ConcurrentLinkedQueue并发队列(基于链表)并发组

基于链表实现的并发队列,使用乐观锁(CAS)保证线程安全。因为数据结构是链表,所以理论上是没有队列大小限制的,也就是说添加数据一定能成功。

<强> ConcurrentLinkedDeque并发队列(基于双向链表)

基于双向链表实现的并发队列,可以分别对头尾进行操作,因此除了先进先出(FIFO),也可以先进后出(费罗),当然先进后出的话应该叫它栈了。

<强> ConcurrentSkipListMap基于跳表的并发图

SkipList即跳表,跳表是一种空间换时间的数据结构,通过冗余数据,将链表一层一层索引,达到类似二分查找的效果

癑AVA并发容器有哪些"

<强> ConcurrentSkipListSet基于跳表的并发组

类似HashSet和HashMap的关系,ConcurrentSkipListSet里面就是一个ConcurrentSkipListMap,就不细说了。

<强> ArrayBlockingQueue阻塞队列(基于数组)

基于数组实现的可阻塞队列,构造时必须制定数组大小,往里面放东西时如果数组满了便会阻塞直到有位置(也支持直接返回和超时等待),通过一个锁ReentrantLock保证线程安全。

用提供操作举个例子:

 public  class  ArrayBlockingQueue, extends  AbstractQueue
  ,,,,,,,implements  BlockingQueue,, java.io.Serializable  {
  ,,,/* *
  ,,,,*,读写共用此锁,线程间通过下面两个条件通信
  ,,,,*,这两个条件和有锁紧密联系(就是锁的方法生成的)
  ,,,,*,类似对象的等待/通知
  ,,,*/,,,final  ReentrantLock 锁;
  
  ,,,/* *,队列不为空的信号,取数据的线程需要关注,*/,,,private  final  Condition  notEmpty;
  
  ,,,/* *,队列没满的信号,写数据的线程需要关注,*/,,,private  final  Condition  notFull;
  
  ,,,//,一直阻塞直到有东西可以拿出来
  ,,,public  E 采取(),throws  InterruptedException  {
  ,,,,,,,final  ReentrantLock  lock =, this.lock;
  ,,,,,,,lock.lockInterruptibly ();
  ,,,,,,,try  {
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null

JAVA并发容器有哪些