ArrayList subscript out-of-bounds issue when adding elements to a multithreaded call to add (java.lang.ArrayIndexOutOfBoundsException)

Source: Internet
Author: User

Recently, when you read the book "Java Virtual Machine in action", see the following example of a multi-threaded use of ArrayList in the Lock and Concurrency section:



Two threads t1 and t2 add data to numberlist at the same time, because ArrayList is thread insecure, so it will cause the added data to have errors, which I can understand, but it is indeed the following error:


I can not understand a bit, ArrayList is not automatic expansion, no length limit, why the array subscript out of the error?

For ease of analysis, I changed the code a little bit:


The result of the execution is:












Sometimes null is also present,


With all sorts of puzzled, to see ArrayList add process:

First, ArrayList is an array-based implementation, and is a dynamic array whose capacity can grow automatically, similar to the dynamic application memory in C, which dynamically grows memory.

For ArrayList, it implements the list interface, and the underlying uses an array to hold all the elements. Its operation is basically an array of operations.

       1, program error  at Java.util.ArrayList.elementData ( arraylist.java:400) and  at Java.util.ArrayList.add (arraylist.java:441), which belong to the Add () method.   

        Source code is as follows:               &NBS P                          ,         &NB Sp                          ,         &NB Sp                          ,         &NB Sp                          ,         &NB Sp       

adds an operation that first calls the ensurecapacityinternal (size + 1), which acts to ensure that the capacity of the array is always sufficient, where The size is the number of tuples in the Elementdata array, initially 0.


in the ensurecapacityinternal () function, use if to determine if the array has no elements, a default size for the array is chosen, and the value at the time of instantiation is selected with a larger value in the default size, and then called ensure Explicitcapacity ().


 function body, Modcount is the number of times that the array has changed size. Then if judged,    If the array length is less than the default capacity of 10, call the method grow () to enlarge the size of the array. 
   
 function grow () Explains how array-based ArrayList are scaled up.  When the array is expanding , the elements in the old array are re-copied to the new array, each time the array capacity grows by approximately 1.5 times times its original capacity. 
       next go back to the Add () function, continue execution,elementdata[size++] = e; This line of code is the problem, and when an element is added, it can be done in two steps: 1. Store this element in the location of Elementdata[size]; 2. Increase the value of Size. 
       In the case of single-threaded runs, if Size = 0, after adding an element, this element is at position 0, and size=1;
 and if in multithreaded situations, such as having two threads, thread A first stores the element in position 0. However, when CPU scheduler thread a pauses, thread B gets the chance to run. Thread B also adds elements to this ArrayList, since Size is still equal to 0 (note that we assume that adding an element is a two-step process, and thread A just completes step 1), so thread B also stores the element in position 0. Then both thread A and thread B continue to run, increasing the value of Size. Well, let's take a look at ArrayList, where the element is actually only one, stored at position 0, and Size equals 2. This is "thread insecure". This explains why NULL is present in the collection. 
   But array subscripts cannot be explained by this alone. We observe the array subscripts at the time of the crossing, respectively 10, 15, 22, 33, 49, and 73. Combined with the above-mentioned array automatic mechanism, the initial length of the array is 10, the first expansion is 15=10+10/2, the second expansion 22=15+15/2, the third expansion of the 33=22+22/2 ... and so on, it's easy to see that cross-boundary anomalies occur at the time of array expansion. 
 This gives me an idea, I guess, because there is no synchronization of this method, resulting in a phenomenon, with the first exception, that is, the subscript 15 o'clock exception example. When 14 elements have been added to the collection, a thread first enters the Add () method, executing the  ensurecapacityinternal (size + 1), the discovery can also add an element, so the array is not expanded, However, the thread is then blocked at this point. Then another thread enters the Add () method, executes  ensurecapacityinternal (size + 1), since the previous thread did not add elements, the size is still 14, There is still no need to expand, so the thread starts adding elements so that size++ becomes 15 and the array is full. And just blocked in elementdata[size++] = e; the thread before the statement begins execution, it adds a 16th element to the collection, and the array has only 15 capacity, so an array subscript out-of-bounds exception occurred! 




ArrayList subscript out-of-bounds issue when adding elements to a multithreaded call to add (java.lang.ArrayIndexOutOfBoundsException)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.