集合类线程不安全问题
ArrayList
List<String> list = new ArrayList<String>();
for(int i=1;i<30;i++){
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8))
}).start();
}
// 1 故障现象
// java.util.ConcurrentModificationException
// 2 导致原因
// 并发争抢修改导致,参考我们的花名册签名情况
// 一个人正在写入,另外一个同学过来抢夺,导致数据不一致异常。并发修改异常
// 3 解决方案
new Vetor<>()
Collections.sychronizedList(new ArrayList<>())
new CopyOnWriteArrayList()
// 4 优化建议(同样的错误不犯两次)
copyWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器object[]添加,而是先将当前容器object[]进行copy,复制出一个新的容器 setArray(newElements);这样做的好处是可以对copyWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyWrite容器也是一种读写分离的思想,读和写不同的容器
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
TrabsferValue小练习
public class TestTransferValue {
public void changeValue1(int a){
a = 66;
}
public void changeValue2(Person person){
person.name = "xxx";
}
public void changeValue3(String a) {
a = "xxx";
}
public static void main(String[] args) {
TestTransferValue transferValue = new TestTransferValue();
// 基本数据类型在存储在栈中
int a = 88;
transferValue.changeValue1(a);
System.out.println(a);
// 引用对象
Person p = new Person();
p.name= "88";
transferValue.changeValue2(p);
System.out.println(p.name);
// 常量池
String str = "888";
transferValue.changeValue3(str);
System.out.println(str);
}