问题:
创建一个ArrayList,然后创建两个线程,每个线程for循环1000次向公共的List里面添加数据,在一个线程读取List当前的大小之后,另一个线程可能已经对List进行了修改。这样就可能导致数据的不一致性,例如一个线程读取到的List大小已经被另一个线程修改了,因此,在这个案例中,最终的列表大小可能不是期望值2000,而是一个小于或大于2000的随机值。这正是ArrayList线程不安全的一个典型表现。
解决方案:
1.使用Vector:Vector类与ArrayList类非常类似,但它的方法是同步的,可以确保在多线程环境中的安全访问和操作
Vector<Integer> list = new Vector<>(); Thread thread1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { list.add(i); } }); Thread thread2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { list.add(i); } }); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("List size: " + list.size()); } }
2.使用CopyOnWriteArrayList:CopyOnWriteArrayList是Java提供的一个线程安全的并发集合类,它通过每次添加、修改或删除元素时创建一个新的底层数组来实现线程安全,这种机制叫做写时复制。
CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>(); Thread thread1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { list.add(i); } }); Thread thread2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { list.add(i); } }); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("List size: " + list.size()); } }
标签:Thread,ArrayList,list,简述,线程,thread2,thread1,new From: https://www.cnblogs.com/xialang/p/17743496.html