关于ArrayList、HashSet、HashMap在并发下不安全的实例以及解决办法
ArrayList:
public class UnSafeList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
发现ArrayList在并发下产生了异常
三个方法解决:
- List<String> list = new Vector<>() JDK1.0出现的
- List<String> list = Collections.synchronizedList(new ArrayList()); Collectons下面的
- List<String> list = new CopyOnWriteArrayList<>(); JUC下面的
都没有问题
但是为什么推荐使用CopyOnWriteArrayList而不是Vector
查看底层源码:
发现Vector使用的是Synchronized关键字,CopyOnWriteArrayList使用的是Lock锁
HashSet:
public class UnSafeSet {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
for (int i = 0; i < 30; i++) {
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set);
}).start();
}
}
}
出现了异常
提供了两种解决办法:
- Set<String> set = Collections.synchronizedSet(new HashSet<>());
- Set<String> set = new CopyOnWriteArraySet(); JUC下面的
解决!!!
并且通过查看源码可知,HashSet的底层是HashMap
HashSet的add() 利用的是HashMap的key不相同的原理
HashMap:
Map<String ,String> map = new HashMap<>();
等价于Map<String ,String> map = new HashMap<>(16,0.75); 参数:初始化容量,加载因子
public class UnSafeMap {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
for (int i = 0; i < 30; i++) {
new Thread(()->{
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
System.out.println(map);
},String.valueOf(i)).start();
}
}
}
出现了并发异常
解决办法:
- Map<String,String> map = Collections.synchronizedMap(new HashMap<>());
- Map<String,String> map = new ConcurrentHashMap<>();
问题解决!!!