10-Java多线程-5、并发容器小结

并发容器小结

一、更多并发容器

1.1 跳跃表SkipList

  • 跳跃表(SkipList)一种概率数据结构。它的思想是以空间换时间,在原链表的基础上形成多层索引,但是某个节点在插入时,是否成为索引,随机决定,因此跳表又称为概率数据结构。它的实现比红黑树简单很多,但是查找和增删效率能够接近平衡二叉树。因为ConcurrentHashMap里空间利用率本身就很低,所以没有引入跳跃表,因为跳表的空间利用率本身不高。
1.1.1 ConcurrentSkipListMap
  • HashMap的并发版本,基于跳跃表实现。
1.1.2 ConcurrentSkipListSet
  • TreeSet的并发版本,基于跳跃表实现,实际上是基于ConcurrentSkipListMap来实现的,值就是ConcurrentSkipListMap里面的key,ConcurrentSkipListMap里面的value保存一个boolean类型的true。

1.2 写时复制容器

  • 写时复制的容器。是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以写时复制容器也是一种读写分离的思想,读和写不同的容器。如果读的时候有多个线程正在向容器添加数据,还是会读到旧的数据,因为写的时候不会锁住旧的容器,只能保证最终一致性。适用读多写少的并发场景,常见应用:白名单/黑名单, 商品类目的访问和更新场景。
    不过写时复制容器存在内存占用问题。
  • JDK中的写时复制容器有:
CopyOnWriteArrayList
CopyOnWriteArraySet

二、非阻塞队列

2.1 ConcurrentLinkedQueue

  • 基于链表的无界线程安全非阻塞队列,底层是个链表,遵循先进先出原则。
  • add,offer将元素插入到尾部,peek(拿头部的数据,但是不移除)和poll(拿头部的数据,但是移除)

三、阻塞队列

3.1 概念、生产者消费者模式

  • 当队列满的时候,插入元素的线程被阻塞,直达队列不满。
  • 队列为空的时候,获取元素的线程被阻塞,直到队列不空。

3.2 常用阻塞队列

阻塞队列备注阻塞/有界?
ArrayBlockingQueue基于数组的有界阻塞队列。按照FIFO原则,要求设定初始大小阻塞有界
LinkedBlockingQueue基于链表的有界阻塞队列。按照FIFO原则,可不设定初始大小,默认Integer.Max_Value阻塞有界
PriorityBlockingQueue支持优先级排序的无界阻塞队列。默认按照自然顺序,可以实现compareTo()方法或者指定构造参数Comparator阻塞无界
DelayQueue使用优先级队列实现的无界阻塞队列。支持延时获取元素,元素必须要实现Delayed接口。适用场景:实现自己的缓存系统,订单到期,限时支付等等阻塞无界
SynchronousQueue不存储元素的阻塞队列。每一个put操作都要等待一个take操作阻塞有界
LinkedTransferQueue基于链表的无界阻塞队列。transfer(),必须要消费者消费了以后方法才会返回,tryTransfer()无论消费者是否接收,方法都立即返回阻塞无界
LinkedBlockingDeque链表组成的双向阻塞队列。可以从队列的头和尾都可以插入和移除元素,实现工作窃取阻塞无界

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值