In-depth understanding of concurrentmap.putifabsent (Key,value) usage

Source: Internet
Author: User
Tags locale

Read the code First: Java code    public class locale {       private  Final static map<string, locale> map = new hashmap<string,locale > ();       public static locale getinstance (String  language, string country,                string variant)  {           //...            String key = some_string;           locale locale = map.get (key);            if  (locale == null)  {                locale = new locale (language,  Country, variAnt);               map.put (key,  Locale);           }            return locale;       }        // ....  }  

The thing to do with this code is:

  Call the Map.get (key) method to determine if there is a value (Locale object) corresponding to the key in the map. If NULL is returned, there is no key-value mapping to find in the map. New a Locale object and put the new object in the map with the key. Finally return the newly created Locale object we expect to ensure that the same key returns the same Local object reference each time the GetInstance method is called. So, just look at the first piece of code, can I ask it to achieve this expectation?   The answer is: in a single-threaded environment can meet the requirements, but in a multithreaded environment, there will be a thread security problem, that is not guaranteed in the case of the same concurrent key return the same Local object reference.   This is because in the above code there is a custom operation called Put-if-absent [1], and this operation exists a race Condition:java code    if  (locale ==  null)  {       locale = new locale (language,  country, variant);       map.put (key, locale);  }     Because after a thread has finished the locale = = NULL judgment to the time when the value is actually put to the map, the other thread may have put the map in the add operation, so that when the put operation, the same key corresponding to the locale object is overwritten, the final The locale reference for the same key returned by the GetInstance method will appear inconsistent. So the put-if-absent operation on the MAP is unsafe (thread safty).   To solve this problem, Java 5.0 introduces the Concurrentmap interface, in which the put-if-absent operation exists in the form of an atomic method Putifabsent (K key, V value). IsAs Javadoc wrote: Java code   /**       * If the specified  key is not already associated       * with a  value, associate it with the given value.       *  This is equivalent to       * <pre>        *   if  (!map.containskey (key))         *       return map.put (key, value);        *   else       *        Return map.get (key);</pre>       * except that the  action is performed atomically.       * .....       */   so you can use this method instead of the operation in the above code. But it's easy to make a mistake when it comes to substitution. Take a look at the following code: Java code    public class locale implements cloneable, serializable  {       private final static ConcurrentMap<String,  Locale> map = new concurrenthashmap<string, locale> ();        public static locale getinstance (string language, string  country,               String  Variant)  {           //...            String key = some_string;            locale locale = map.get (key);            if  (locale == null)  { &nbsp             locale = new locale ( language, country, variant);                map.putifabsent (Key, locale);           }            return locale;        }       // ....  }     This code uses the concurrent of the MAP Form (Concurrentmap, Concurrenthashmap), and simply use the statement map.putifabsent (key, Locale). This also does not guarantee that the same key returns the same Locale object reference.   the error here ignores the Putifabsent method has a return value, and the return value is important 。 Still watching Javadoc:java code   /**    *  @return   the previous value  associated with the specified key, or    *          <tt>null</tt> if there was no mapping  for the key.    *          (A <tt >null</tt> return can also indicate that the map     *         previously associated <tt>null</tt > with the key,    *         if  the implementation supports null values.)     */   Returns the value if Key-value already exists (when the method is called). If the mapping of the key is not found in the map when it is called, return a null value "  Therefore, it is very necessary to judge the return value when using the Putifabsent method. As shown below (jaImplementation code in the Va.util.Locale Class): Java code   

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.