在大家学习Java基础时都知道,ArrayList、LinkedList、HashMap、HashSet等常用的容器类都是线程不安全的,如果有多个线程访问它们时将会出现意外结果,下边我们讲解如果使用线程安全的集合类。
- 使用java.util包下线程安全的集合类
- 使用Collections工具类将非线程安全的集合包装成线程安全的集合
- 使用juc中的并发集合类
Vector与Hashtable
Vector
Vector是一个古老的基于顺序表的实现,从Java1.0开始就有,底层是用数组存储数据,从源码我们可以看它的线程安全是在内部方法上加synchronized关键字来实现的,因此,这种线程安全往往效率低下!
Hashtable
Hashtable与Vector一样,从源码中看它也是在内部方法上加synchronized关键字来实现的,同样,它也是效率低下的!
Collections处理非线程安全的集合
Collections可以将任意的集合类包装成线程安全的,它内部提供了synchronizedXxx()方法,我们可以调用 Collections.synchronizedXxx()方法传入一个普通的集合类,它给我们返回一个包装后的线程安全的实现类,其实内部还是使用我们原始集合类存储数据,只不过是在调用原始集合类方法时加了synchronized,因为这种方法同样是效率低下的!
JUC中的集合类
java.util.concurrent包下为我们提供了大量的与Set、List、Map、Queue数据结构对应的高性能的线程安全集合类,如下
- CopyOnWriteArrayList
- CopyOnWriteArraySet
- ConcurrentHashMap
- ConcurrentLinkedQueue
- ConcurrentLinkedDeque
- ConcurrentMap
- ConcurrentNavigableMap
- ConcurrentSkipListMap
- ConcurrentSkipListSet
CopyOnWriteArrayList
在一些场景中了存大大量读取操作,只有少数写操作(修改),这时对于读操作完全没必要加锁,使用多个线程进行读取操作,提高线程性能,JDK中提供了CopyOnWriteArrayList集合类,它是List集合的实现,对读取操作不用加锁,写入也不会阻塞读取,只有写与写之间是同步等待的。因此大大提供了程序性能
当进行写操作(add()、set() 和 remove() 等等),需要复制整个基础数组,开销很大!
当进行读取操作(使用迭代器进行遍历)时速度很快,并且不会与其他线程发生冲突!
CopyOnWriteArraySet
ConcurrentHashMap
ConcurrentNavigableMap
ConcurrentLinkedQueue
ConcurrentSkipListMap
ConcurrentSkipListMap内部是基于跳表来实现的
跳表内部所有链表的元素都是可排序的