ArrayList线程不安全以及解决方案

ArrayList:ArrayList底层为一个Object类型的数组,初始大小为10,在多线程操作ArrayList时会产生各种各样的线程不安全问题,该文章首先还原问题,用三种方法解决该问题。

  • 问题还原
public class ArrayListExample {
    public static void main(String[] args) {
        List list = new ArrayList();
        //List list = Collections.synchronizedList(new ArrayList<>());
        for(int i = 1 ;i<=30;i++){
            new Thread(() ->{
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

可以看到使用ArrayList所导致的问题如上所示

  • 问题解决

1.使用Vector代替,但是Vector在java中的出现比ArrayList出现的还要早,导致性能下降,一般不使用这种方式

2.使用Collections.synchronizedList(new ArrayList<>())解决该问题,解决方式如下

public class ArrayListExample {
    public static void main(String[] args) {
        //List list = new ArrayList();
        List list = Collections.synchronizedList(new ArrayList<>());
        for(int i = 1 ;i<=30;i++){
            new Thread(() ->{
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

3.使用CopyOnWriteArrayList,读写分离,写入时复制

public class ArrayListExample {
    public static void main(String[] args) {
        List list = new CopyOnWriteArrayList();
        //List list = Collections.synchronizedList(new ArrayList<>());
        for(int i = 1 ;i<=30;i++){
            new Thread(() ->{
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

以上三种方式问题都可以解决,推荐第二种或者第三种。

发布了12 篇原创文章 · 获赞 9 · 访问量 580

猜你喜欢

转载自blog.csdn.net/weixin_39475445/article/details/104406617