Concurrentmodificationexception Exception (HashSet processing error)

Source: Internet
Author: User
Tags concurrentmodificationexception
Java.util.ConcurrentModificationException exception
1.

A java.util.ConcurrentModificationException exception occurred today when writing an access Agent with a cache function because the exception is a non-capturing exception and is very rare, so it took some time to find the problem, which was originally traversed through iterator, as This exception occurs when the HashMap is directly manipulated, and then continues to traverse with the previous iterator, indicating that its hashmap has been modified.

The source code snippet is as follows: Caches is a HashMap object

     String Samekeypart = accesserclassname + "@" + MethodName + "@" +parameterkeystring + "@";
     Iterator keys = Caches.keyset (). Iterator ();
     String key = null;
     while (Keys.hasnext ()) ... {
       key = (String) keys.next ();
       if (Key.startswith (Samekeypart)) ... {
         caches.remove (key);
       }
     }


The workaround is to delete it by its corresponding iterator, and the following code snippet is modified:

     String Samekeypart = accesserclassname + "@" + MethodName + "@" +parameterkeystring + "@";
     Iterator keys = Caches.keyset (). Iterator ();
     String key = null;
     while (Keys.hasnext ()) ... {
       key = (String) keys.next ();
       if (Key.startswith (Samekeypart)) ... {
         keys.remove ();
       }
     }
I feel this piece of article is very specific:

http://blog.csdn.net/myyate/article/details/1943040

    set<object> BB = new hashset<object> ();
    Bb.add ("23242");
    Bb.add (integer.valueof);
    Iterator it = Bb.iterator ();
    while (It.hasnext ()) {
        Object ele = It.next ();
        Bb.remove (ele);    Wrong
    }


    set<object> bb = new hashset<object> ();
    Bb.add ("23242");
    Bb.add (integer.valueof);
    Iterator it = Bb.iterator ();
    while (It.hasnext ()) {
        it.next ();
        It.remove ();
    }


2.

How many times have you encountered the following tips when composing multithreaded code:
Exception in thread "main" java.util.ConcurrentModificationException

There are several reasons why this anomaly occurs. One is to invoke the delete operation directly on the collection instead of on the enumerator. The second is when different threads try to make additions or deletions to the collection.

The first step in this solution is to synchronize the code so that other threads do not have to make or delete records while enumerating. But if each enumeration process is computationally complex or part of a database access, this synchronization can lead to dire consequences. To reduce the negative impact, you can copy a read-only enumerator, remove the synchronization, and then use the method shown in the following code:

Private list List;
  public void Add (Object obj) {
  synchronized (list) {
  list.add (obj);
  }
  }
  public void Perform () {
  Iterator Iterator = null;
  Synchronized (list) {
  iterator = new Copiediterator (List.iterator ());
  }
  while (Iterator.hasnext ()) {
  //perform resource or CPU hungry work
  }
  }


It is important to remember that Copiediterator is not a clone, just a read-only copy, so it does not maintain all of its original functionality. Most importantly, you can no longer invoke the Copiediterator.remove method. The implementation of Copiediterator.remove is as follows:

public class Copiediteratorimplements Iterator {
  private Iterator Iterator = null;
  Public Copiediterator (Iterator itr) {
  LinkedList list = new LinkedList ();
  while (Itr.hasnext ()) {
  List.add (Itr.next ());
  }
  This.iterator = List.iterator ();
  }
  public Boolean Hasnext () {
  return this.iterator.hasNext ();
  }
  public void Remove () {
  throw new Unsupportedoperationexception ("This Isa read-only iterator.
  ");
  Public Object Next () {
  return this.iterator.next ();
  }
  }


The read-only copy of the enumerator minimizes the time spent in the synchronization state, thereby enhancing the overall efficiency.

3.

When you try to modify the contents of Collection/map directly while using Fail-fast iterator to iterate over the Collection or map, even if you are running in a single thread, Java.util.ConcurrentModificationException exceptions will also be thrown.
Iterator is working in a separate thread, and has a mutex lock. Iterator is created after the creation of a single-chain index table pointing to the original object, when the original object number changes, the contents of the index table will not be synchronized changes, so when the index pointer moves back to find the object to iterate, so according to Fail-fast principle Iterator The java.util.ConcurrentModificationException exception is thrown immediately.

So iterator is not allowed to be changed by iterative objects while working. But you can delete the object using Iterator's own method, remove (), and the Iterator.remove () method maintains the consistency of the index while deleting the current iteration object.

The interesting thing is that if your Collection/map object actually has only one element, the concurrentmodificationexception exception will not be thrown. This is why it is stated in Javadoc: It would bewrong to the write a program, depended on this exception for ITSCORRECTNESS:CONCURRENTM Odificationexception should is used only todetect bugs.

  importjava.util.*;   
     Public final Classmytest {private static HashMap p_maplist = Newhashmap (2);    
         Privatemytest () {} public static voidinit () {//If only There is more than one element Inmap,   
         The concurrentmodificationexception would notbe//thrown.   
         P_maplist.put (New String ("Hello"), NewString ("World"));   
     P_maplist.put (New String ("goto"), NewString ("hell"));   
         } public static void Clear () throwsexception{Iterator Ptmpkeys =null;   
         Longptmpkeylong;   
         Ptmpkeys =p_maplist.keyset (). iterator ();   
         String Pcurkey =null;   
         String Pcurobj =null;   
             while (Ptmpkeys.hasnext ()) {Pcurkey = (String) ptmpkeys.next ();   
    
             Pcurobj = (String) p_maplist.get (Pcurkey);   
             P_maplist.put (Pcurkey,null);   
             You can not remove element in Map objectdirectly. P_mapliSt.remove (Pcurkey);   
             But you can remove the current element by Iteratoritself.   
    
             Ptmpkeys.remove ();   
         System.out.println (Pcurkey + "removed.");   
         } System.out.println (P_maplist.size () + "entries left afteriterator.");   
     Ptmpkeys =null; } public static void Main (String[]args) throwsexception{mytest.in   
         It ();   
     Mytest.clear ();  }   
 }


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.