4.并发容器

简介

ConcurrentHashMap;//线程安全的HashMap
CopyOnWriteArrayList;//在读多写少的场合性能很好,远优于vector
ConcurrentLinkedQueue;//线程安全的LinkedList
BlockingQueue;//阻塞队列,适合作数据共享的通道
ConcurrentSkipListMap;//这是一个Map,使用跳表进行快速查找
此外Vector也是线程安全的,Collections工具类可以帮助我们将任意集合包装成线程安全的集合

一. 线程安全的HashMap

1. 使用Collections工具类

Map<Object, Object> m= Collections.synchronizedMap(new HashMap<>());

其原理为通过mutex对m进行互斥操作,比如Map.get()

public V get(Object key){
	synchronized(mutex){return m.get(key);}
}

虽然这个包装的map能满足线程安全的要求,但是其性能很差,无论是对map的读或者锁,都需要获得mutex的锁,这会导致所有对map的操作都进入等待状态,直到mutex可用

2.ConcurrentHashMap

专门对并发进行了优化,适合多线程的场合

二、线程安全的List

1.使用Collections工具类

List<String> l = Collections.synchronizedList(new LinkedList<>());

2.高效读写的队列 ConcurrentLinkedQueue

等待

三、高效读取:不变模式下的CopyOnWriteArrayList

类似读写锁,但是其读写线程之间不会相互阻塞,只有写和写之间需要进行同步等待

当这个list需要修改时,并不修改原有内容,而是对原有数据进行一次复制,对副本进行修改,然后在用修改完的副本替换原来的数据。并且因为array变量时volatile类型,因此修改完后,读取线程可以立即察觉到这个修改

四、数据共享通道BlockingQueue

与前面几种容器不同,BlockingQueue是一个接口,而不是具体实现,他的主要实现有很多,我们主要介绍ArrayBlockingQueue和LinkedBlockingQueue
ArrayBlockingQueue
基于数组实现,属于有界队列,大小在初始化时指定
LinkedBlockingQueue
基于链表实现,属于无界队列,大小动态变化
BlockingQueue之所以适合作为数据共享的通道,关键在于Blocking,Blocking是阻塞的意思,系统如何知道有新消息在等待呢,可以让系统定时查看队列,但是很明显浪费资源,BlockingQueue则是当有消息来时,他会将线程唤醒,省去了系统开销

ArrayBlockingQueue

向队列中压入元素可使用offer和put方法
	offer方法是若有位置则进入,否则返回false
	put方法是有位置进入,否则等待,知道有空位
从队列弹出元素有poll和take方法,poll类似offer,而take类似put方法
ArrayBlockingQueue内部类似循环队列,有两个元素takeIndex和putIndex,总是从takeIndex取,从putIndex进。

五、随机数据结构:跳表(SkipList)

类似b树

SkipList

posted @ 2020-06-01 21:05  INnoVation-V2  阅读(145)  评论(0编辑  收藏  举报