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(); } } }
以上三种方式问题都可以解决,推荐第二种或者第三种。