HashSet不安全
HashSet也是线程不安全的,底层没有进行任何线程同步处理。
在hashset的源码中,底层是用hashmap实现的:
每次add的时候,把值放在了map对象中的key,而map对象的value则全部统一放一个常量:
在下面的demo中,hashset在多线程情况下和arrayList一样会抛出java.util.ConcurrentModificationException
/**
* @author zkw
* @Description HashSet不安全
*/
public class ThreadHashSet {
public static void main(String[] args) {
Set<String> list = new HashSet<>();
for (int i = 0; i < 30; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
}, i+"").start();
}
}
}
解决方法 使用 CopyOnWriteArraySet
public class ThreadHashSet {
public static void main(String[] args) {
Set<String> list = new CopyOnWriteArraySet<>();
for (int i = 0; i < 30; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
}, i+"").start();
}
}
}
HashMap不安全
使用HashMap空参构造,其初始容量是16,负载因子0.75
初始容量和负载因子都可以自定义,构造方法如下:
HashMap同上面两个类一样,在多线程情况下会出现并发修改异常java.util.ConcurrentModificationException
解决方法:使用ConcurrentHashMap
public static void main(String[] args) {
Map<String,String> list = new ConcurrentHashMap<>();
for (int i = 0; i < 30; i++) {
new Thread(()->{
list.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
}, i+"").start();
}
}