我们看下面这段代码
现在这段代码是线程安全的,如果我们修改代码,修改为10个线程
报错了
我们看报错信息
是并发修改异常
在刚才的案例中,我们看到,并发下,ArrayList是不安全的,下面将提供两种解决方法
使用vector
package org.Test6;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
public class ListTest {
public static void main(String[] args) {
List<String> list=new Vector<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
我们使用其他工具类,使用Collections
使用 Collections.synchronizedList() 方法将普通的 ArrayList 转换为一个线程安全的 List 集合
。通过对 list 进行同步化操作,可以保证在多线程环境下对 list 的访问是线程安全的。
Collections.synchronizedList() 方法返回一个线程安全的 List 对象,该对象内部使用同步机制来确保多线程环境下的安全访问。具体来说,它会对 List 的各种操作(如添加、删除、获取等)进行同步化处理,以避免并发修改引发的线程安全问题,比如数据不一致或异常。
好处如下:
需要注意的是,虽然 Collections.synchronizedList() 方法可以确保对集合的基本操作是线程安全的,但在进行复合操作时仍然需要额外的同步措施。例如,在循环遍历 list 并进行复合操作时,仍需要使用外部的同步机制,比如使用 synchronized 关键字或 Lock 接口。
此外,如果只是在单线程环境下使用集合,或者可以保证对集合的访问是单线程的,那么不一定需要使用线程安全的集合类。因为线程安全的集合类在性能上会有一些额外开销,所以在单线程环境下使用普通的集合类可能更加高效。
package org.Test6;
import java.util.*;
public class ListTest {
public static void main(String[] args) {
List<String> list= Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
使用juc包下的CopyOnWriteArrayList方法
CopyOnWriteArrayList 是一个线程安全的 List 集合,它的特点是在进行写操作时会复制一份原有的数组,并在新的数组上进行修改
,从而避免了并发修改导致的问题。因此,CopyOnWriteArrayList 是一种适用于读多写少场景下的线程安全集合。
CopyOnWriteArrayList 的读取操作不需要加锁,因为读取时直接读取原数组中的数据即可。而对于写操作,由于修改的是新的数组,因此写操作不会影响到正在读取旧数组的线程
,从而避免了并发修改导致的问题。当写操作完成后,CopyOnWriteArrayList 会将新数组替换旧数组,从而使得所有线程都能读取到新的数据。
写入的时候避免覆盖,造成数据问题
package org.Test6;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListTest {
public static void main(String[] args) {
List<String> list= new CopyOnWriteArrayList<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!