一、并发集合简介
JDK的并发容器大部分都在java.util.concurrent包中。
1.ConcurrentHashMap:一个高效的HashMap,可以理解为线程安全的HashMap。
2.CopyOnWrtieArrayList:与ArrayList相似,在读多谢少的场景中,性能比Vector好很多。
3.ConcurrentLinkedQueue:高效的并发队列,使用链表实现,可以看做一个线程安全的LinkedList。
4.BlockingQueue:一个借口,内部用链表数组实现,表示阻塞队列,适合用于数据共享的通道。
5.ConcurrentSkipListMap:跳表的实现,一个map,运用调表的数据结构实现快速查找。
此外,Vector也是线程安全的集合,但是性能低下。Collections工具类可以把任意集合包装成线程安全的集合。
二、线程安全的HashMap
HashMap在多线程环境下会产生很多问题,那么需要一个线程安全的HashMap的一种方案就是使用Collections.SynchronizedMap()包装HashMap。public static Map M = Collecntions.synchronizedMap(new HashMap());
有关Map相关的功能都是委托HashMap()实现的,SynchronizedMap主要负责保证线程安全。
这个包装的Map可以实现线程安全,但是在多线程的环境下性能并不是很好。在高并发中需要一个更加专业的并发HashMap:ConcurrentHashMap.
三、List的线程安全
队列,链表在程序中极其常用,在java中,ArrayList和Vector都是使用数组作为其内部实现,两者最大的不同在于Vector是线程安全的,而ArrayList不是,此外LinkedList使用链表的数据结构实现了List。但是LinkedList并不是线程安全。可以使用Collection.synchronizedList()方法包装任意List。
public static List<String> l = Collections.synchronizedList(new LinkedList<String>());
四、高效读写队列:ConcurrentLinkedQueue
队列也是程序中常用的数据结构之一。JDK中提供一个ConcurrentLinkedQueue类用来实现高并发的队列。这个队列在高并发环境中差不多是性能最好的队列。在ConcurrentLinkedQueue中,定义的节点Node核心如下。
private static class Node<E>{
volatile E item;
volatile Node<E> next;
其中item是用来标记表示标记元素的,比如当列表中存放String时,item的类型就是String类型。字段next表示当前Node的下一个元素,这样每一个Node就能环环相扣,ConcurrentLinkedQueue内部有两个重要字段,head和tail,分别表示链表的头部和尾部,它们都是Node类型,对于head来说它永远不会为null,并且通过head以及succ()后继方法,一定能完整的遍历整个链表,tail则表示队列的尾部。然而ConcurrentLinkedQueue内部实现非常复杂。它允许在运行时链表处于多于多个不同的状态。以tail为例,tail的更新并不是及时的,而是可能会产生拖延现象,tail的更新会产生滞后,并且每次更新会跳跃两个元素。