In-depth understanding of the Java Collection Series three: The HashMap of the Dead circle

Source: Internet
Author: User

Because in the company project occasionally encounter HashMap death cycle caused cpu100%, after restarting the problem disappears, interval time will recur. Here today to carefully analyze the problems caused by HashMap in the case of multithreading:

1. After a multi-threaded put operation, a get operation causes a dead loop.

2. After a multithreaded put non-null element, the get operation gets a null value.

3, multi-threaded put operation, resulting in the loss of elements.

Dead Cycle Scene Replay

Below I use a simple demo to simulate the HashMap dead loop:

1  Public classTestextendsThread2 {3     StaticHashmap<integer, integer> map =NewHashmap<integer, integer> (2);4     StaticAtomicinteger at =NewAtomicinteger ();5     6      Public voidRun ()7     {8          while(At.get () < 100000)9         {Ten Map.put (At.get (), At.get ()); One at.incrementandget (); A         } -}

Where both map and at are static, which is the resource shared by all threads. Then 5 threads concurrently operate the HashMap:

1  Public Static voidMain (string[] args)2      {3Test T0 =NewTest ();4Test T1 =NewTest ();5Test t2 =NewTest ();6Test t3 =NewTest ();7Test T4 =NewTest ();8 T0.start ();9 T1.start ();Ten T2.start (); One T3.start (); A T4.start (); -}

Repeated execution several times, this situation indicates a dead loop:

Next we'll look at the CPU and stack conditions:

From the stack you can see: Thread-3 due to the HashMap expansion operation led to the dead loop.

Normal expansion process

Let's take a look at the single-threaded case, the normal rehash process

1, suppose our hash algorithm is a simple key mod the size of the table (that is, the length of the array).

2, the top is the old hash table, where the hash table size=2, so key=3,5,7 in mod 2 after the conflict in table[1] this position.

3, the next hash table expansion, resize=4, and then all the <key,value> re-hash distribution, the process is as follows:

In a single-threaded scenario, everything looks wonderful and the expansion process is pretty smooth. Next, look at the expansion in the concurrency scenario.

Capacity expansion in concurrent situations

1, first assume that we have two threads, respectively, in red and blue marked.

2, the source code of the expansion part:

1 voidtransfer (entry[] newtable) {2entry[] src =table;3         intNewcapacity =newtable.length;4          for(intj = 0; J < Src.length; J + +) {5Entry<k,v> e =Src[j];6             if(E! =NULL) {7SRC[J] =NULL;8                  Do {9Entry<k,v> next =E.next;Ten                     inti =indexfor (E.hash, newcapacity); OneE.next =Newtable[i]; ANewtable[i] =e; -E =Next; -} while(E! =NULL); the             } -         } -}

3, if the thread one executes to the 9th line of code is suspended by the CPU scheduling, to execute threads 2, and thread 2 to execute the above code is complete. Let's take a look at the state of this time:

4, then the CPU switch to thread one up, execute 8-14 lines of code, first place 3 this entry:

It is important to note that thread two has finished executing, and now all the entry in the table are up-to-date, that is, the next of 7 is 3,3 next is null, and now the first cycle is over, and 3 is properly placed. See what happens next:

1, e=next=7;

2, E!=null, cycle continue

3, Next=e.next=3

4, E.next 7 of Next point 3

5, place 7 This entry, now:

After placing 7, run the code:

1, e=next=3;

2, the judgment is not empty, continue to circulate

3, next= E.next here is the next null for 3

4, e.next=7, 3 of the next point 7.

5, place 3 This entry, the state of this time

This time in fact there is a cycle of death, the position of 3 moving nodes nodded, pointing to 7 of this entry; Before that, the 7 next also points to 3 of the entry.

The code then executes, E=next=null, and the condition is judged to terminate the loop. This expansion is over. However, if there is a query (whether it is the iteration or the expansion of the query), it will hang in the table "3" position. Now back to the beginning of the article to see the demo, is hanging dead in the expansion phase of the transfer this method above.

It's not like I'm going to have to get a bunch of data in the test environment specifically to demonstrate this. If we think about it, we can conclude that if the two entry adjacent to the expansion are still allocated to the same table position after expansion, there will be a dead loop bug. In a complex production environment, this situation, although uncommon, may be encountered.

Multithreaded put operation, resulting in element loss

The following is an introduction to the missing element problem. This time we take the 3, 5, 7 order to demonstrate:

1, if the thread one executes to the 9th line of code is suspended by CPU scheduling:

2, thread two execution completion:

3, this time then the execution line Cheng, first place 7 this entry:

4, then place 5 This entry:

5, because the next of 5 is null, at this time the expansion action ends, resulting in 3 of this entry lost.

Other

The problem was reported to Sun, but Sun did not think it was a problem. Because HashMap does not support concurrency.

If you want to use HashMap in concurrent scenarios, there are two workarounds:

1, use Concurrenthashmap.

2. Use the Collections.synchronizedmap (mao<k,v> m) method to turn the HashMap into a thread-safe map.

In-depth understanding of the Java Collection Series three: The HashMap of the Dead circle

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.