并发笔记(七)线程安全容器

一.线程安全容器

在这里插入图片描述

1.List(CopyOnWriteArrayList)

CopyOnWriteArrayList内部维护一个数组,成员变量arr指向这个数组,读操作也就是迭代Iterator遍历的就是这个数组,如果在读的时候,同时存在写操作的时候,会将arr复制一份,然后在复制的数组上进行进行元素的添加,执行操作完成操作之后将arr指向新的数组。

适用与:读多写很少的场景
优点:读无锁,读的效率很高
缺点:浪费内存,读写的短暂不一致

注意:CopyOnWriteArrayList的迭代器不支持增删改,只支持读

2.Map

ConcurrentHashMap 的 key 是无序的,而 ConcurrentSkipListMap 的 key 是有序的。所以如果你需要保证 key 的顺序,就只能使用 ConcurrentSkipListMap。

ConcurrentSkipListMap 里面的 SkipList 本身就是一种数据结构“跳表”。跳表插入、删除、查询操作平均的时间复杂度是 O(log n),理论上和并发线程数没有关系,所以在并发度非常高的情况下,若你对 ConcurrentHashMap 的性能还不满意,可以尝试一下 ConcurrentSkipListMap。

3.Set

CopyOnWriteArraySetConcurrentSkipListSet,使用场景可以参考CopyOnWriteArrayList 和 ConcurrentSkipListMap。

4.Queue

队列可以分为:阻塞和非阻塞,单端和双端,组合起来共四类:

4.1 单端阻塞队列

ArrayBlockingQueue:数组结构,单锁,支持有界

LinkedBlockingQueue:链表结构,双锁,最大容量Integer.MAX_VALUE,效率相比ArrayBlockQueue更高,支持有界

SynchronousQueue:容量为0,语义和之前的Exchanger是一样的,理解为手递手的传递东西,其中take和put方法都是阻塞的。
***线程池中的应用比较多,但是我不会,查了一些资料也是说有应用,但是具体的应用还是不清楚。***

SynchronousQueue的应用案例:jdk提供的CachedThreadPool

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
LinkedTransferQueue:像是SynchronousQueue的加强版,可以传递多个参数,并且put方法不再是阻塞的了,但是提供了一个强大的transfer方法,阻塞的等待消费者消费。并且效率比SynchronousQueue和LinkedBlockingQueue的效率更高。

PriorityBlockingQueue:堆结构的阻塞队列,支持优先级的出队

DelayQueue:支持等待时间的优先出队

4.2双端阻塞队列

LinkedBlockingDeque。

4.3单端非阻塞队列

ConcurrentLinkedQueue。

4.4双端非阻塞队列

ConcurrentLinkedDeque。

总结

上诉的队列中,只有ArrayBlockingQueue和LinkedBlockingQueue(ConcurrentLinkedDeque)是有界的,其他均是无界的,使用的时候尽量使用有界队列。

Queue相对于list的区别,添加了对线程友好的API:offer、peek、poll
Queue子类BlockingQueue添加了对象成友好的API:put和take(阻塞的)。
对于容器理解的还是比较少,目前只是清楚表面一点,以后在扩充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值