問題和解決方法
描述:1:我們在在多線程情況下用ArrayList a=new ArrayList();在add(param)添加信息常遇到ConcurrentModificationException
即并發(fā)修改異常
原因:多個線程爭搶修改信息時候,當一個線程正在修改卻被其他線程搶占去同一個位置的修改權造成修改錯誤,丟數(shù)據(jù)
代碼--問題復現(xiàn)
public class UnSafeArrayList {
public static void main(String[] args){
List<String> list = new ArrayList<>();
for (int i = 0; i < 40; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.print(list);
},String.valueOf(i)).start();
}
}
}
解決方法:
1不用ArrayList 改用vector集合(原因vertor里的add方法加了synchronized,同一時刻只允許一個線程訪問和修改)
-
2使用java.util.Collections工具類,它提供了對List Map Set的封裝,使其安全
List<Object> list = Collections.synchronizedList(new ArrayList<>());
image.png 3使用java.util.Concurrent里有一些如CopyOnWriteArrayList,CopyOnWriteSet的包裝型ArrayList();(好處可以并發(fā)的讀)
挖掘CopyOnWriteArrayList:(寫時復制-讀寫分離)
CopyOnWriteArrayList
add
CopyOnWriteArrayList的add方法解析
圖形描述CopyOnWriteArrayList的add方法
CopyOnWriteArrayList與Collections.synchronizedList的性能對比(轉)
寫操作:在線程數(shù)目增加時CopyOnWriteArrayList的寫操作性能下降非常嚴重泽西,而Collections.synchronizedList雖然有性能的降低,但下降并不明顯。
讀操作:在多線程進行讀時拖陆,Collections.synchronizedList和CopyOnWriteArrayList均有性能的降低,但是Collections.synchronizedList的性能降低更加顯著