集合类不安全的问题

并发修改异常(ArrayList)

ArrayList不安全

原因:

是由于高并发下add方法没有加锁,该方法不安全

引发:

java.util.ConcurrentModificationException 高并发修改异常

代码Demo

public class ContainerNotSafeDemo{
	public static void main(Stirng[] args){
		List<String> list=new ArrayList<>();
		
		for(int i=1;i<30;i++){
			new Thread(()->{
				list.add(UUID.randomUUID().toString().subString(0,8));
				System.out.println(list);
			},String.valueOf(i).start());
		}
	}
}

解决方案:

1)使用Vector方法替换ArrayList方法,因为Vector的add方法加了锁syncronized

new Vector<>()

2)使用Collections的工具类:

Collections.syncronizedList(new ArrayList<>())

补充:Collection代表接口,而Collections表示集成接口的辅助工具类

3)使用写时复制,也就是读写分离

CopyOnWriteArrayList

CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行Copy,复制出一个新的容器Object[] newElements,然后心得容器Object[] newElements里添加元素,添加完元素之后,再将原容器得引用指向新的容器setArray(newElements)。

这样做得好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写在不同的容器

 

Set

ArraySet也是不安全的类,就像ArrayList一样。解决方案也相同有3个,第二个用的是Collections.syncronizedSet(),第三个Set的读写分离用的是CopyOnwriteArraySet()方法。但是CopyOnwriteArraySet()的底层实现仍然是CopyOnwriteArrayList()

常见面试题:

HashSet的底层是什么?

HashSet的底层是HashMap

而Set的add方法只有一个值的原因:

Set的add调用的方法还是map.put,add的传值就是put的key,而put的value是一个常量Present

Map

与上面2个一样都是不安全的,new HashMap<>().put(xx,xx)不安全

使用Collections.syncronizedMap()

有一定不同的是,第三种方法使用的是new ConcurrentHashMap<>()

猜你喜欢

转载自blog.csdn.net/di_ko/article/details/115067337