高并发下你还敢用ArrayList?过来看看CopyOnWriteArrayList吧!

本文分析了ArrayList在多线程环境下的线程不安全问题,提出了几种解决方案,重点介绍了CopyOnWriteArrayList的工作机制。通过源码解析,展示了CopyOnWriteArrayList如何通过写时复制实现线程安全,并探讨了其弱一致性的迭代器。文章指出CopyOnWriteArrayList适用于读多写少的场景,但也存在内存占用和数据一致性问题。
摘要由CSDN通过智能技术生成

​微信公众号:Zhongger
我是Zhongger,一个在互联网行业摸鱼写代码的打工人!
关注我,了解更多你不知道的【Java后端】打工技巧、职场经验、生活感悟等

一、ArrayList线程不安全

在Java的集合框架中,想必大家对ArrayList肯定不陌生,单线程的情况下使用它去做一些CRUD的操作是非常方便的,先来看看这个例子:

public class ListTest {
   
    public static void main(String[] args) {
   
        List<String> arrayList = new ArrayList<>();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        for (String s : arrayList) {
   
            System.out.println(s);
        }
    }
}

其输出结果就是与元素被添加进ArrayList的顺序一样,即:

a
b
c

但是到了多线程的情况下,ArrayList还会像单线程一样执行结果符合我们的预期吗?我们再来看下这个例子:

public class ListTest {
   
    public static void main(String[] args) {
   
        List<String> arrayList = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
   
            new Thread(()->{
   
                arrayList.add(UUID.randomUUID().toString().substring(0,5));
                //往list中添加一个长为5的随机字符串
                System.out.println(arrayList);
                //读取list
            },"线程"+(i+1)).start();
        }
    }
}

由输出结果:

Exception in thread "线程10" 
Exception in thread "线程1" 
Exception in thread "线程14"
Exception in thread "线程3" 
Exception in thread "线程5" 
Exception in thread "线程2"
Exception in thread "线程6" 
Exception in thread "线程21" 
Exception in thread "线程23" 
Exception in thread "线程28" 
Exception in thread "线程29" 
java.util.ConcurrentModificationException

我们发现,多线程的情况下,有多个线程对ArrayList添加元素,同时又会有多个元素对ArrayList进行元素的读取,这样使得程序抛出了ConcurrentModificationException并发修改异常,所以我们可以下定结论:ArrayList线程不安全!

二、解决ArrayList线程不安全的方案

1、使用Vector类

我们知道,Java集合中的Vector类是线程安全的,可以用Vector去解决上述的问题。

public class ListTest {
   
    public static void main(String[] args) {
   
        List<String> arrayList = new Vector<>();
        for (int i = 0; i < 30; i++) {
   
            new Thread(()->{
   
                arrayList.add(UUID.randomUUID().toString().substring(0,5));
                //往list中添加一个长为5的随机字符串
                System.out.println(arrayList);
                //读取list
            },"线程"+(i+1)).start
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值