单线程触发

下面这种写法本身就是错的,
就算换成 CopyOnWriteArrayList 也不规范,效率也不如 iterator 调用 remove 高。
不能在遍历中使用 list.remove。

  1. List<Integer> list = new ArrayList<>();
  2. for (int i = 1; i < 10; i++) {
  3. list.add(i);
  4. }
  5. for (Integer item : list) {
  6. list.remove(item);
  7. }

解决:使用 Collection 内置的 iterator 调用 remove

只要是继承自 Collection 的类都可以使用这种方式

  1. Iterator<Integer> iterator = list.iterator();
  2. while (iterator.hasNext()) {
  3. Integer item = iterator.next();
  4. if (item < 10) {
  5. iterator.remove();
  6. }
  7. }

简化写法:

  1. list.removeIf(item -> item < 10);

多线程触发

多个线程同时修改线程不安全的容器时就会触发。

方案一:
使用 Collections.synchronizedSet() 工具类方法把容器操作转换成同步

方案二(推荐):

容器换成 JUC 的 CopyOnWrite系列

  • ArrayList 改为 CopyOnWriteArrayList
  • HashSet 改为 CopyOnWriteArraySet
  • �HashMap 改为 ConcurrentHashMap