ArrayList
public class ThreadTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();//CopyOnWriteArrayList();
for (int i =1; i<=30 ; i++) {
new Thread(() -> {
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println(list.toString());
}).start();
}
}
}
报错信息:
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at com.atguigu.thread.ThreadTest.lambda$main$0(ThreadTest.java:19)
at java.lang.Thread.run(Thread.java:745)
异常原因: 因为在数据存储过程中有多个线程同时操作list集合,造成并发修改异常
解决方案:
List<String> list = new CopyOnWriteArrayList();
使用线程安全的CopyOnWriteArrayList集合类
源码解析:
/**
* Appends the specified element to the end of this list.
*/
public boolean add(E e) {
//对数据存储过程加锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
//把原来的数组数据拷贝到比原数组大于1的数组中
Object[] newElements = Arrays.copyOf(elements, len + 1);
//把要添加的元素添加到最后的位置
newElements[len] = e;
//把新数组赋值给集合
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
HashSet
public class ThreadTest {
public static void main(String[] args) {
Set<String> set = new HashSet<>();//CopyOnWriteArrayset();
for (int i =1; i<=30 ; i++) {
new Thread(() -> {
set.add(UUID.randomUUID().toString());
set.add(UUID.randomUUID().toString());
set.add(UUID.randomUUID().toString());
set.add(UUID.randomUUID().toString());
System.out.println(set.toString());
}).start();
}
}
}
报错信息:
Exception in thread "Thread-21" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at com.atguigu.thread.ThreadTest.lambda$main$0(ThreadTest.java:20)
at java.lang.Thread.run(Thread.java:745)
解决方案:
Set<String> set = new CopyOnWriteArraySet<>();
HashMap
原因和异常同上;
解决方式:
Map<String, String> map = new ConcurrentHashMap<>();