ArrayList 線程不安全的案例和解決方案
-
故障現象
public class ContainerDemo { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < 100; i++) { new Thread(() -> { list.add(random.nextInt(10)); System.out.println(list); }).start(); } } }
發現報
java.util.ConcurrentModificationException
-
導致原因
- 併發修改導致的異常
-
解決方案
-
new Vector();
-
Collections.synchronizedList(new ArrayList<>());
-
new CopyOnWriteArrayList<>();
-
/** CopyOnWriteArrayList * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */ 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(); } }
-
-
優化建議
- 在讀多寫少的時候推薦使用 CopeOnWriteArrayList 這個類