CopyOnWriteArraySet
-
Set不安全
-
多条线程执行set添加方法
//java.util.ConcurrentModificationException 并发修改异常 public class Test04 { 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); },String.valueOf(i)).start(); } } } //Exception in thread "6" Exception in thread "7" Exception in thread "3" Exception in thread "18" Exception in thread "23" Exception in thread "25" 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 java.lang.String.valueOf(String.java:2981) at java.io.PrintStream.println(PrintStream.java:821) at com.saxon.demo.Test04.lambda$main$0(Test04.java:11)
解决方案
- 使用Collections下的Collections.synchronizedSet(new HashSet<>()); 方法创建Set集合
- 使用JUC下的CopyOnWriteArraySet方法
//java.util.ConcurrentModificationException 并发修改异常 public class Test04 { public static void main(String[] args) { // Set<String> set = new HashSet<>(); /*解决方案 * 1. Set<String> set=Collections.synchronizedSet(new HashSet<>()); * 2. Set<String> set=new CopyOnWriteArraySet<>();*/ // Set<String> set = Collections.synchronizedSet(new HashSet<>()); Set<String> set=new CopyOnWriteArraySet<>(); for (int i = 0; i < 30; i++) { new Thread(()->{ set.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(set); },String.valueOf(i)).start(); } } }
-
HashSet底层是什么?
HashSet底层就是HashMap的底层实现原理,就只是加了个key不能被重复
public HashSet() {
map = new HashMap<>();
}
// add: set本质就是 map 中 key是无法重复的!
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
PRESENT :private static final Object PRESENT = new Object();//常量