多线程环境下优先使用无状态bean(不带属性的类)和不使用共享变量(每一个线程持有自己的变量(threadlocal或者局部变量)),如果在多线程环境下,必须使用共享变量,请参考如下:
import java.util.ArrayList;
import java.util.UUID;
public class ArrayListNoSafeDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
/**
*1.故障现象
* java.util.ConcurrentModificationException
* 2.导致原因
* 并发争抢修改导致的
* 3.解决方案
* 3.1 new Vector();
* 3.2 Collections.synchronizedList(new ArrayList<>());
* 3.3 new CopyOnWriteArrayList<>();
* 写时复制
* CopyOnWrite写时复制的容器。往一个容器添加添加元素的时候,不直接往当前容器object[]中添加,而是现将容器object[]复制,
* 得到一个新的容器Object[] newElements,然后新的容器里添加元素,添加完元素之后,在将原容器的引用指向新的容器
* setArray(newElements);这样做的好处是可以将原来的容器CopyOnWrite并发的读,而不需要枷锁,因为当前容器不会添加任何元素。
*
* 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();
* }
* }
*
* 4.优化建议(同样的错误不犯第2次)
*/
}