vector、synchronizedList、CopyOnWriteArrayList 三者的区别
参考 https://blog.csdn.net/dimu9293/article/details/107729756
三者底层原理
1、vector是通过在每个方法加synchronized实现,包括最简单的size()方法
public synchronized int size() {
return elementCount;
}
public synchronized boolean isEmpty() {
return elementCount == 0;
}
2、synchronizedList是通过在每个方法内部加 synchronized实现,包括最简单的size()方法
public int size() {
synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return m.isEmpty();}
}
public boolean containsKey(Object key) {
synchronized (mutex) {return m.containsKey(key);}
}
public boolean containsValue(Object value) {
synchronized (mutex) {return m.containsValue(value);}
}
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
}
3、CopyOnWriteArraylist是通过复制一份副本,然后通过修改副本之后再赋值回去,lock是new()出来的,用于在set,add等写操作的时候进行锁操作
final transient Object lock = new Object();
public E set(int index, E element) {
synchronized (lock) {
Object[] es = getArray();
E oldValue = elementAt(es, index);
if (oldValue != element) {
es = es.clone();
es[index] = element;
setArray(es);
}
return oldValue;
}
}
//获取迭代器的时候是复制了一个新的数组
public Iterator<E> iterator() {
return new COWIterator<E>(getArray(), 0);
}
三者的优缺点
类型 | 缺点 | 优点 |
---|---|---|
vector | 所有操作都要加锁,性能不佳 | 即使在高并发环境下都能保证数据的一致性 |
synchronizedList | 同上 | 同上 |
CopyOnWriteArrayList | 写操作会有一定的延迟 | 只有写加锁,读不加锁 |
解析:
1、由于vector与synchronizedList都是通过加synchronized实现,两者性能上差距并不大。但是由于每次调用方法都要加锁,导致在大数据量的情况下性能不理想。
2、CopyOnWriteArrayList 由于写锁读不锁使得性能更好,但是由于写操作是在副本上进行的,在数据量大的情况下数组的复制比较耗时,所以写完后不能立马体现出来,有一定的延迟。
CopyOnWriteArrayList 读写不一致的场景示例
1.循环中删除元素不报错
例子
List<String> list = new CopyOnWriteArrayList(); //CopyOnWriteArrayList换成ArrayList则直接报错
list.add("A1");
list.add("A2");
list.add("A3");
for (String str : list) {
if ("A1".equals(str)) {
list.remove(str);
}
}
System.out.println(list);
//运行结果
[A2, A3]
2.迭代过程中往list添加或减少元素不会立马体现
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList();
list.add("A1");
list.add("A2");
list.add("A3");
Iterator<String> it = list.iterator();
list.add("A4");
while (it.hasNext()){
System.out.println(it.next());
}
//运行结果
A1
A2
A3
3.不支持remove操作
为了保证数据不错乱,CopyOnWriteArrayList不支持在迭代器中进行remove操作。
在CopyOnWriteArrayList中
public Iterator<E> iterator() {
return new COWIterator<E>(getArray(), 0);
}
在 COWIterator 中
public void remove() {
throw new UnsupportedOperationException();
}
测试
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList();
list.add("A1");
list.add("A2");
list.add("A3");
Iterator<String> it = list.iterator();
list.add("A4");
while (it.hasNext()){
it.remove();
System.out.println(it.next());
}
结果:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList.java:1120)
at STU_CopyOnWriteArraylist.read(STU_CopyOnWriteArraylist.java:20)
at STU_CopyOnWriteArraylist.main(STU_CopyOnWriteArraylist.java:7)
本文来自博客园,作者:NeverLateThanBetter,转载请注明原文链接:https://www.cnblogs.com/do-it-520/p/vector_synchronizedList_CopyOnWriteArrayList.html
韶华易逝,不能虚度年华。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?