[JUC source code] Several questions about CopyOnWriteArrayList

Put a portal before the start of the article: [JUC source code] CopyOnWriteArrayList source code analysis . For the following questions, what is unclear, you can understand the source code.

1. What are the similarities and differences between CopyOnWriteArrayList and ArrayList?

  • Similarities: The underlying data structure is the same, both are array data structures. The APIs provided are all to operate on the array structure, so that we can use it better.

  • Difference: CopyOnWriteArrayList is thread-safe and can be used directly in a multi-threaded environment without locking.

2. By what means does CopyOnWriteArrayList achieve thread safety?

Answer: Mainly:

  1. The array container is modified by the volatile keyword, which ensures that after the array memory address is modified by any thread, other threads will be notified;
  2. All modification operations on the array are locked to ensure that only one thread can modify the array at the same time. For example, when I add, I cannot remove;
  3. During the modification process, the original array is copied and modified on the new array. During the modification process, the original array will not be affected.

Through the above three points to ensure thread safety.

3. In the add method, after locking the array, isn't it already thread-safe? Why do I need to copy the old array?

Answer: Indeed, after the array is locked, it can be guaranteed that only one thread can add to the array at the same time. There is definitely no problem in the multi-threaded environment under the same single-core CPU, but our current machines are all multi-core CPUs. If we do not copy the new array and modify the memory address of the original array container, the volatile visibility effect cannot be triggered, and the threads under other CPUs will not be able to perceive that the array has been modified before, which will cause the multi-core CPU Thread safety issues.

Assuming that we do not copy the copy, but directly modify the value on the original array, the memory address of the array will not change, and when the array is volatile modified, the memory address of the array must be changed in time to notify other threads, memory The address is unchanged, only when the value of the array element changes, it is impossible to notify other threads of the fact that the value of the array element changes.

4. There will be performance loss when copying the old array. What should I pay attention to when using it?

Answer: In the batch operation, try to use the addAll and removeAll methods instead of the add and remove methods in the loop. The main reason is that the add and remove methods are used in the for loop. In each operation, a copy of the array will be performed. (Even multiple times), it is very performance-intensive, and the addAll and removeAll methods are optimized at the bottom. The entire operation will only perform an array copy. It can be seen that the more data in the batch operation, the more obvious the high performance of the batch method. .

5. Why does the array structure change during the iteration of CopyOnWriteArrayList, so ConcurrentModificationException is not thrown?

Answer: Mainly because every time CopyOnWriteArrayList is operated, a new array will be generated, and when iterating, it still holds a reference to the old array, so the change in the array structure we are talking about is to replace the old array with the new array. The structure of has not changed, so no exception will be thrown.

6. The inserted data happens to be in the middle of the List. How many times do the two lists copy the array? why?

  • ArrayList only needs to be copied once. Assuming that the inserted position is 2, only the data after position 2 (including 2) needs to be moved one bit back, so copy once.

  • CopyOnWriteArrayList is copied twice, because CopyOnWriteArrayList adds the step of copying the data of the old array to the new array.

    Some people may think of this way: first copy the old array to the new array, and then move the data after 2 back by one. This is indeed a way of copying, but the total amount of data copied is n + n- 2 = 2n -2, and the underlying implementation of CopyOnWriteArrayList is more flexible.

    In short, copy the data from the old array 0 to 2 to the new array, reserve a position for the new array 2, and then copy the last data from the old array 3 to the new array. This copy method can reduce us Copy data, the total amount of data copied in this way is n.

    Although it is copied twice, the copied data is still the size of the old array, and the design is very clever.

Guess you like

Origin blog.csdn.net/weixin_43935927/article/details/108782055