同步容器
在之前看的ArrayList,LinkedList,HashMap等的源码中,我们通过注释知道了这些个容器类都不是线程安全的对象,如果要实现同步,那么可以通过手动使用synchronized加锁,或者使用SynchronizedXXX(XXX可以是Map,List,Set等)来包装这些容器类。
这里主要介绍同步容器实现线程安全的方法,以及略微介绍有哪些个并发容器,具体并发容器的细节介绍写在各章中
SynchronizedXXX类
SynchronizedXXX类是Collections类中实现的同步对象,在主要的方法中使用synchronized加锁来进行同步,我们使用synchronizedList为例,来查看以下这些同步容器是如何实现的
同步类的构造函数需要传入对应的非同步容器
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
同步类方法的实现也非常简单,就是调用传入非同步容器的方法,不过在方法调用时使用synchronized关键字进行同步操作
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
public int indexOf(Object o) {
synchronized (mutex) {return list.indexOf(o);}
}
public int lastIndexOf(Object o) {
synchronized (mutex) {return list.lastIndexOf(o);}
}
public boolean addAll(int index, Collection<? extends E> c) {
synchronized (mutex) {return list.addAll(index, c);}
}
Vector,Stack,HashTable
除了SynchronizedXXX这一类同步容器外,Vector,Stack和HashTable这三个也是同步容器,同步实现的方法就是在读和写的方法上加上synchronized关键字
Vector对标ArrayList,也是一个动态数组
Stack就是数据结构中的栈,继承自Vector
HashTable对标HashMap,不过key和value均不能为null,线程同步的键值对容器
并发容器
同步容器用synchronized关键字简单的锁住了整个容器,可以想见,在并发量较大的情况下,效率肯定不高,所以除了上述的同步容器之外,java还提供了并发容器,这些并发容器不像同步容器那样会锁住整个类,实现线程安全的机制也不相同
list并发容器:CopyOnWriteArrayList
set并发容器:CopyOnWriteArraySet, ConcurrentSkipListSet
map并发容器:ConcurrentHashMap, ConcurrentSkipListMap