When we are complicated by adding value to the ArrayList, can appear when excessive concurrent ConcurrentModificationException (abnormal) concurrent modification,
List list =new ArrayList<>(); for (int i = 0; i <100; I++) {new Thread(()->{list.add(" I'm here "); System.out.println(list); }).start(); } / / * * * * * * * * * * * * * * * * * will quote us the following Exception * * * * * * * * * * * * * * * * the Exception in the thread "thread - 86" is Java. Util. ConcurrentModificationExceptionCopy the code
The cliche is that ArrayList is not secure, make a section of source code, this look is not secure
Vector is safe, but synchronized is inefficient, and the operation is not friendly to expand, modify, and allocate memory (whispering: synchronized has been optimized so many times that its performance is pretty good).
As the title suggests, the solution is JUC’s CopyOnWrite, which is similar to redis persistence. It is safe to test CopyOnWrite. At 1.8 CopyOnWrite uses ReentrantLock
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(); }}Copy the code
I see jdk12 using synchronized
What should I do? Let’s see why; Both are exclusive reentrant locks, and synchronized is much more convenient and concise than ReentrantLock when not involving interrupts, timeouts, etc. (If you take a closer look, you’ll see that 12 has one less new Object array than the previous version, haha);
After looking at the above code, you might ask, this is also using synchronized code block, I use synchronized code block with ArrayList is not good; Here we look at this. Lock and the array defined;
# Volatile is a lightweight lock that has visibility but no atomic properties. # If volatile is applied to a variable, it will be used as a variable. If a field is accessed by multiple tasks at the same time, the field should be volatile. If a field is accessed by multiple tasks at the same time, the field should be volatile. Final transient Object lock = new Object(); private transient volatile Object[] array;Copy the code
So synchronized guarantees thread-safety, while volatile guarantees data security
If you look at the way this graph is read, it doesn’t add anything that involves locking so it can be read concurrently;
Read the above two definitions should probably understand, CopyOnWrite is suitable for read more write less business, can concurrently read, each copy of the memory is also a great consumption, specific business specific analysis; over
Well, today’s unhappiness is over, tomorrow will still shine, baby!
Scatter flowers, the end!!
A dreamer without a dream