先抛个砖头,那就问下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<>();
好了这次就到这里了,下次再见。
本文探讨了ArrayList在多线程环境中的线程安全问题,指出其modCount++操作的非原子性和无同步修饰导致的数据不一致。为解决这个问题,提出了两种替代方案:一是使用Collections.synchronizedList进行包装,二是采用java.util.concurrent并发包中的CopyOnWriteArrayList。这两个选项可在高并发场景中确保集合操作的安全性。此外,还提到了如何将不安全的HashMap转换为线程安全的ConcurrentHashMap。
686

被折叠的 条评论
为什么被折叠?



