"Learning Essay -2" - HashMap is not thread safe (jdk8 also cause an infinite loop, the reason yet to identify)

HashMap

basic concept

            HashMap achieved by the previous array plus jdk7 list and added in the red-black tree jdk8, the length of the chain 8, when converted to red-black tree, the list is reduced to 6 drops. Default initialization array capacity 16, each expansion is a power of 2, default load factor is 0.75

           As we all know, HashMap is thread-unsafe, insecure as to how a law, or to run the code and see the effect, only feel.



HashMap thread-safe test code

           Code launched two threads were a total of map data stored in a total of 100,000.

public class HashMapTestThread {


    static Map<String,String> map = new HashMap<String,String>();


    public static class AddThread implements Runnable{

        int start=0;

        public AddThread(int start){

            this.start = start;

        }

        @Override
        public void run(){
            for (int i = start; i < 100000; i+=2) {
                map.put(Integer.toString(i),Integer.toBinaryString(i));
            }
        }

    }

    public static void main(String[] args) throws Exception{
        Thread t1 = new Thread(new HashMapMultiThread.AddThread(0));
        Thread t2 = new Thread(new HashMapMultiThread.AddThread(1));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(map.size());
    }


}

There are three possible operating results substantially:

1. The program ends normally, the result is correct, map.siz () result 100000 (run several times not a success)

2. The program ends normally, the result is less than 100 000 (this occurs is high probability), as shown below:

Here Insert Picture Description

3. The program will not end, with visible computer speed becomes hot, this time without saying that the cycle of death, cause of death cycle, jdk7 because the first interpolation caused by the expansion of the list when looped, jdk8 under solves this problem , but will still cause an infinite loop, the reason being unclear.





Results less data, error cause analysis


           Data less reason is very simple, when two threads operate on the same node, before a thread after thread operations are overwritten. For example: After thread 1 has a node A to be inserted in the hash array behind No. 4, after the thread 2 there are two hash Node B also inserted behind the 4-bit array, the result should be the correct 4-> A-> B, or 4-> B-> a, No. 4, but if the access nodes 1 and 2 simultaneously, i.e., case No. 4 did not come to the node and add a, add B did not have time, so that 1 and 2 are seen four empty begin add back 4, thread 1 add up fast chips, slow hand thread 2, the thread 1 thus modified was overwritten thread 2, into 4-> B, a modified thread on a lost.



Results infinite loop error cause analysis


           3 because the results of the program never finishes, the computer gradually heat, so check the running cpu with the top command, you can see pid1977 already cpu200% in the run, as shown below:

Here Insert Picture Description

Then, the stack information which jstack print run below the jdk7:

Here Insert Picture Description
As can be seen in FIG: get out in the two threads are HashMap.put, the positioning line 494 to the HashMap:

Here Insert Picture Description
           This place looks like two threads within the data traversing the HashMap, this time because the list has to ring the traversal has become an endless loop.

           Cause jdk7 in an infinite loop that two threads simultaneously expansion rehash, causing the chain to form a ring.

           When rehash jdk7 using the linked list becomes the order after the first interpolation method, migration, i.e., A-> B-> C into a C-> B-> A, this time, if the thread 1 and 2 while the expansion, both creation of a temporary storage node A-> B, preparation for this operation, the thread 1 continues to operate at this time, a temporary thread 2, the thread 1 goes to the C-> B-> a, node B is true at this time point a, and then thread 2 continues, continue to operate under temporary node A-> B, then settle a, go to the thread 1 has been placed node scored a real good operation node, that is B-> a continues to operate, so a good placement of the original point B, and then continue to win a node a continues to operate, let a point B, causing the a point B, point B to a circular linked list. (Probably introduced here, details please refer to https://www.jianshu.com/p/1e9cf0ac07f4 )

           jdk8 head is no longer using the interpolation method, instead of using interpolation tail, after insertion of the same order of the list, thereby avoiding the place chain ring, but a new cycle of death causes.



FIG jdk8 run as follows:

Here Insert Picture Description
The problem also occurs jdk8 dead follow next, positioning code to the 1824 line: Here Insert Picture Description
the specific reasons yet to identify ah, seems to be a red-black tree ring ...

Released two original articles · won praise 0 · Views 31

Guess you like

Origin blog.csdn.net/qq_35217741/article/details/105324735