多线程下如何操作ArrayList,Set
//不安全的写法 ,会报出 ConcurrentModificationException,当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
public static void main(String[] args) { List<String> list = new ArrayList(); for (int i = 0;i<10;i++){ new Thread(()->{ list.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(list); }).start(); } }
改进方法1:用vector,核心用了synchronized
List<String> list = new Vector<>();
改进方法2:用Collections工具类下的方法,核心用了synchronized
List<String> list = Collections.synchronizedList(new ArrayList<>());
改进方法3:用JUC下面的 CopyOnWriteArrayList,写入时复制,
List<String> list = new CopyOnWriteArrayList<>();
//写入时复制的核心。复制一份 public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); } }
二、Set
类似的安全操作
Set<String> set = Collections.synchronizedSet(new HashSet<>());
Set<String> set = new CopyOnWriteArraySet<>();
//hashSet底层是HashMap
public HashSet() { map = new HashMap<>(); }
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

浙公网安备 33010602011771号