MAP
WeakHashMap 和普通的HashMap相比,当除了自身有对key的引用外,此key没有其他引用那么此map会自动丢弃此值,从而解决HashMap对象中key-value资源无法释放,导致内存泄露。
WeakHashMap的key采用的是弱引用。只要key不被外部引用,就会被回收。HashMap则相反。
ConcurrentHashMap 线程安全,采用了分段锁的设计, 将一个HashMap分成N段,使用key的hashCode来确定分配到那个字段,只有在同一分段内才存在竞态关系,每个分段相当于一个HashTable,执行效率相当于提升了N倍。
LinkedHashMap 如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现。非线程安全。
SortedMap(接口)
LIST
CopyOnWriteArrayList 适用于读操作>>写操作的情况。在写时拷贝,也就是如果需要对CopyOnWriteArrayList的内容进行改变,首先会拷贝一份新的List并且在新的List上进行修改,最后将原List的引用指向新的List。
线程安全地遍历,因为如果另外一个线程在遍历的时候修改List的话,实际上会拷贝出一个新的List上修改,而不影响当前正在被遍历的List。
CopyOnWriteArraySet
什么是CopyOnWrite容器?
CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
Queue
java.util.concurrent包下的四种阻塞队列:
ArrayBlockingQueue有界队列(java.util.Concurrent包,用于多线程编程),有助于防止资源耗尽,但可能较难调整和控制。
ArrayBlockingQueue是一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素,队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列检索操作则是从队列头部开始获得元素。
这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致放入操作受阻塞;试图从空队列中检索元素将导致类似阻塞。
LinkedBlockingQueue*队列,基于单向链表的实现。
PriorityBlockingQueue*阻塞队列,基于数组,通过使用堆这种数据结构实现将队列中的元素按照某种排序规则进行排序,从而改变先进先出的队列顺序,提供开发者改变队列中元素的顺序的能力。队列中的元素必须是可比较的,即实现Comparable接口,或者在构建函数时提供可对队列元素进行比较的Comparator对象。
所有的添加元素最后都是调用offer方法,2步:扩容+存储,大体流程为:
1.加锁,检查元素数量是否大于等于数组长度,如果是,那就扩容,扩容没必要使用主锁,先释放锁,使用cas自旋锁,容量最少翻倍,释放自旋锁,可能存在竞争,检查下,是否扩容,如果扩容那就复制数组,再度加主锁;
2.看构造入参是否有comparator,有就使用,没有就自然排序,从数组待插入位置父节点开始比较大,如果大于父节点,那就直接待插入位置插入,否则就跟父节点交换,然后循环向上查找,数量加1,通知非空条件队列take,最后释放锁。
DelayQueue Delayed 元素的一个*阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。当一个元素的getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满。此队列不允许使用 null 元素。