先抛个砖头,那就问下ArrayList是线程安全的吗?
大家肯定都知道不是线程安全的。
我们平时在做有关多线程操作集合时使用ArrayList集合,会发现控制台提示:java.util.ConcurrentModificationException,
分析它的内部源码,
public void add(int index, E element) {
rangeCheckForAdd(index);
modCount++;//不是一个原子操作,高并发情况,会出现数据一致性问题
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
通过观察很明显就可以观察有两处是线程不安全的
一.modCount++ 不是原子性,在高并发情况下会出现数据不一致行。
二.高并发写入数据没synchronized修饰,抛出异常。
既然ArrayList在高并发情况下不适用,什么可以取代呢?
有时api提供的有些类时线程不安全的,这些适合场景是单线程,不存在并发。
在高并发场景往往可以在Collections工具类或者在java.util.concurrent.ConcurrentHashMap(JUC)并发包找到对应线程安全的。
方法一:Collections.synchronizedList(new ArrayList<>()); 取代new ArrayList<>();【Collections工具类】
List<String> list =Collections.synchronizedList(new ArrayList<>());
看上图列表还有对应的Map和Set,
也就是说不安全的HashMap我们也可以写成线程安全的。
Map<String,String> map=Collections.synchronizedMap(new HashMap<>());
方法二:new CopyOnWriteArrayList<>();取代new ArrayList<>();【java.util.concurrent.ConcurrentHashMap(JUC)并发包】
List<String> list =new CopyOnWriteArrayList<>();
看上图列表还有对应的Map
也就是说不安全的HashMap我们也可以写成
Map<String,String> map=new ConcurrentHashMap<>();
好了这次就到这里了,下次再见。