[concurrency-interest] ConcurrentModificationException notapplicable to Map.values()?

David Holmes davidcholmes at aapt.net.au
Tue Dec 15 20:07:18 EST 2009


Because CHM iterators support concurrency - from the CHM class javadoc:

"Similarly, Iterators and Enumerations return elements reflecting the state
of the hash table at some point at or since the creation of the
iterator/enumeration. They do not throw ConcurrentModificationException. "

Cheers,
David Holmes
  -----Original Message-----
  From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Will McQueen
  Sent: Wednesday, 16 December 2009 11:01 AM
  To: concurrency-interest at cs.oswego.edu
  Subject: [concurrency-interest] ConcurrentModificationException
notapplicable to Map.values()?


        Hi,

        I'm puzzled why ConcurrentModificationException is not thrown in the
case where I use a ConcurrentHashMap instead of HashMap. The code below is
single-threaded so that ConcurrrentModificationException should definitely
be thrown (as opposed to "good-faith-effort"). [Ref: JCIP "Iterators and
ConcurrentModificationException"]

        Below is my code that shows 2 cases -- the first where
ConcurrentModificationException is not thrown (that's the case I don't
understand), and the second case shows where it is thrown.

        This example below shows ConcurrenHashMap, which I use in the
multi-threaded version of my code. So technically I could use just a HashMap
for this single-threaded demo.... but then this would not reproduce this
issue. That is, puzzlingly, case #1 *does* throw the expected
ConcurrentModificationException when I use a HashMap instead of
ConcurrentHashMap (!).

        public final class QuickTest {
            public static void main(String[] args) {
                /*** CASE 1 ****/
                final Map<String,String> map;
                map = new ConcurrentHashMap<String,String>();
                map.put("a","1");
                map.put("b", "2");
                map.put("c", "3");

                Collection<String> view = map.values();
                Iterator<String> itr = view.iterator();
                String e1 = itr.next();
                System.out.println(e1);
                view.remove(e1); //direct removal through the collection,
not through the iterator
                String e2 = itr.next(); //??? Why doesn't this throw
ConcurrentModificationException?
                System.out.println(e2);

                /*** CASE 2 ***/

                final List<String> list;
                list = new ArrayList<String>();
                list.add("1");
                list.add("2");
                list.add("3");

                itr = list.iterator();
                e1 = itr.next();
                System.out.println(e1);
                list.remove(e1); //direct removal through the collection,
not through the iterator
                e2 = itr.next(); //(throws ConcurrentModificationException,
as expected)
                System.out.println(e2);
            }
        }

        Your insight and help is greatly appreciated. Thank you.

        Cheers,
        Will


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20091216/dfc2d4fc/attachment.html>


More information about the Concurrency-interest mailing list