You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jo...@apache.org on 2009/06/18 00:28:09 UTC

svn commit: r785844 - /commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java

Author: joehni
Date: Wed Jun 17 22:28:09 2009
New Revision: 785844

URL: http://svn.apache.org/viewvc?rev=785844&view=rev
Log:
Removing entries with the MapIterator may also result in a ConcurrentModificationException (COLLECTIONS-330).

Modified:
    commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java

Modified: commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java?rev=785844&r1=785843&r2=785844&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java (original)
+++ commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java Wed Jun 17 22:28:09 2009
@@ -26,6 +26,7 @@
 import junit.textui.TestRunner;
 
 import org.apache.commons.collections.BulkTest;
+import org.apache.commons.collections.MapIterator;
 import org.apache.commons.collections.OrderedMap;
 import org.apache.commons.collections.ResettableIterator;
 
@@ -455,6 +456,87 @@
         } catch (IndexOutOfBoundsException ex) {}
     }
     
+    // TODO: COLLECTIONS-330
+    public void todoTestSynchronizedRemoveFromMapIterator() throws InterruptedException {
+
+        final LRUMap map = new LRUMap(10000);
+        
+        final Map exceptions = new HashMap();
+        final ThreadGroup tg = new ThreadGroup(getName()) {
+            public void uncaughtException(Thread t, Throwable e) {
+                exceptions.put(e, t.getName());
+                super.uncaughtException(t, e);
+            }
+        };
+
+        final int[] counter = new int[1];
+        counter[0] = 0;
+        final Thread[] threads = new Thread[50];
+        for (int i = 0; i < threads.length; ++i) {
+            threads[i] = new Thread(tg, "JUnit Thread " + i) {
+
+                public void run() {
+                    int i = 0;
+                    try {
+                        synchronized (this) {
+                            notifyAll();
+                            wait();
+                        }
+                        Thread thread = Thread.currentThread();
+                        while (i < 1000  && !interrupted()) {
+                            synchronized (map) {
+                                map.put(thread.getName() + "[" + ++i + "]", thread);
+                            }
+                        }
+                        synchronized (map) {
+                            for (MapIterator iter = map.mapIterator(); iter.hasNext();) {
+                                if (map.get(iter.getValue()) == this) {
+                                    iter.remove();
+                                }
+                            }
+                        }
+                    } catch (InterruptedException e) {
+                        fail("Unexpected InterruptedException");
+                    }
+                    if (i > 0) {
+                        synchronized (counter) {
+                            counter[0]++;
+                        }
+                    }
+                }
+
+            };
+        }
+
+        for (int i = 0; i < threads.length; ++i) {
+            synchronized (threads[i]) {
+                threads[i].start();
+                threads[i].wait();
+            }
+        }
+
+        for (int i = 0; i < threads.length; ++i) {
+            synchronized (threads[i]) {
+                threads[i].notifyAll();
+            }
+        }
+
+        Thread.sleep(1000);
+
+        for (int i = 0; i < threads.length; ++i) {
+            threads[i].interrupt();
+        }
+        for (int i = 0; i < threads.length; ++i) {
+            synchronized (threads[i]) {
+                threads[i].join();
+            }
+        }
+
+        assertEquals("Exceptions have been thrown: " + exceptions, 0, exceptions.size());
+        assertTrue("Each thread should have put at least 1 element into the map, but only " 
+                + counter[0] + " did succeed", counter[0] >= threads.length);
+    }
+    
     public void testSynchronizedRemoveFromEntrySet() throws InterruptedException {
 
         final Map map = new LRUMap(10000);
@@ -536,7 +618,7 @@
                 + counter[0] + " did succeed", counter[0] >= threads.length);
     }
     
-    // TODO: COLLECTIONS-3
+    // TODO: COLLECTIONS-330
     public void todoTestSynchronizedRemoveFromKeySet() throws InterruptedException {
 
         final Map map = new LRUMap(10000);



Re: svn commit: r785844 - /commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java

Posted by sebb <se...@gmail.com>.
On 17/06/2009, joehni@apache.org <jo...@apache.org> wrote:
> Author: joehni
>  Date: Wed Jun 17 22:28:09 2009
>  New Revision: 785844
>
>  URL: http://svn.apache.org/viewvc?rev=785844&view=rev
>  Log:
>  Removing entries with the MapIterator may also result in a ConcurrentModificationException (COLLECTIONS-330).
>
>  Modified:
>     commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java
>
>  Modified: commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java
>  URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java?rev=785844&r1=785843&r2=785844&view=diff
>  ==============================================================================
>  --- commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java (original)
>  +++ commons/proper/collections/trunk/src/test/org/apache/commons/collections/map/TestLRUMap.java Wed Jun 17 22:28:09 2009
>  @@ -26,6 +26,7 @@
>   import junit.textui.TestRunner;
>
>   import org.apache.commons.collections.BulkTest;
>  +import org.apache.commons.collections.MapIterator;
>   import org.apache.commons.collections.OrderedMap;
>   import org.apache.commons.collections.ResettableIterator;
>
>  @@ -455,6 +456,87 @@
>          } catch (IndexOutOfBoundsException ex) {}
>      }
>
>  +    // TODO: COLLECTIONS-330
>  +    public void todoTestSynchronizedRemoveFromMapIterator() throws InterruptedException {
>  +
>  +        final LRUMap map = new LRUMap(10000);
>  +
>  +        final Map exceptions = new HashMap();
>  +        final ThreadGroup tg = new ThreadGroup(getName()) {
>  +            public void uncaughtException(Thread t, Throwable e) {
>  +                exceptions.put(e, t.getName());
>  +                super.uncaughtException(t, e);
>  +            }
>  +        };
>  +
>  +        final int[] counter = new int[1];
>  +        counter[0] = 0;
>  +        final Thread[] threads = new Thread[50];
>  +        for (int i = 0; i < threads.length; ++i) {
>  +            threads[i] = new Thread(tg, "JUnit Thread " + i) {
>  +
>  +                public void run() {
>  +                    int i = 0;
>  +                    try {
>  +                        synchronized (this) {
>  +                            notifyAll();
>  +                            wait();
>  +                        }
>  +                        Thread thread = Thread.currentThread();
>  +                        while (i < 1000  && !interrupted()) {
>  +                            synchronized (map) {
>  +                                map.put(thread.getName() + "[" + ++i + "]", thread);
>  +                            }
>  +                        }
>  +                        synchronized (map) {
>  +                            for (MapIterator iter = map.mapIterator(); iter.hasNext();) {

Surely there is a missing iter.next() here?

I tried adding it, and the test passes - i.e. the failure is nothing
to do with the remove()

>  +                                if (map.get(iter.getValue()) == this) {
>  +                                    iter.remove();
>  +                                }
>  +                            }
>  +                        }
>  +                    } catch (InterruptedException e) {
>  +                        fail("Unexpected InterruptedException");
>  +                    }
>  +                    if (i > 0) {
>  +                        synchronized (counter) {
>  +                            counter[0]++;
>  +                        }
>  +                    }
>  +                }
>  +
>  +            };
>  +        }
>  +
>  +        for (int i = 0; i < threads.length; ++i) {
>  +            synchronized (threads[i]) {
>  +                threads[i].start();
>  +                threads[i].wait();
>  +            }
>  +        }
>  +
>  +        for (int i = 0; i < threads.length; ++i) {
>  +            synchronized (threads[i]) {
>  +                threads[i].notifyAll();
>  +            }
>  +        }
>  +
>  +        Thread.sleep(1000);
>  +
>  +        for (int i = 0; i < threads.length; ++i) {
>  +            threads[i].interrupt();
>  +        }
>  +        for (int i = 0; i < threads.length; ++i) {
>  +            synchronized (threads[i]) {
>  +                threads[i].join();
>  +            }
>  +        }
>  +
>  +        assertEquals("Exceptions have been thrown: " + exceptions, 0, exceptions.size());
>  +        assertTrue("Each thread should have put at least 1 element into the map, but only "
>  +                + counter[0] + " did succeed", counter[0] >= threads.length);
>  +    }
>  +
>      public void testSynchronizedRemoveFromEntrySet() throws InterruptedException {
>
>          final Map map = new LRUMap(10000);
>  @@ -536,7 +618,7 @@
>                  + counter[0] + " did succeed", counter[0] >= threads.length);
>      }
>
>  -    // TODO: COLLECTIONS-3
>  +    // TODO: COLLECTIONS-330
>      public void todoTestSynchronizedRemoveFromKeySet() throws InterruptedException {
>
>          final Map map = new LRUMap(10000);
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org