You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2018/03/02 01:22:06 UTC

[2/2] groovy git commit: Add test for GROOVY-8486

Add test for GROOVY-8486


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/61e79d8d
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/61e79d8d
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/61e79d8d

Branch: refs/heads/master
Commit: 61e79d8dc587035105549bd5e48d13564befcebc
Parents: c366fdb
Author: sunlan <su...@apache.org>
Authored: Fri Mar 2 09:21:58 2018 +0800
Committer: sunlan <su...@apache.org>
Committed: Fri Mar 2 09:21:58 2018 +0800

----------------------------------------------------------------------
 .../groovy/runtime/memoize/MemoizeTest.groovy   | 62 ++++++++++++++++++++
 1 file changed, 62 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/61e79d8d/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy b/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
index 5c80530..7c74463 100644
--- a/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
+++ b/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
@@ -121,6 +121,68 @@ public class MemoizeTest extends AbstractMemoizeTestCase {
         assert c.mcSoftRef() == 1
     }
 
+    // GROOVY-8486
+    void testMemoizeConcurrently() {
+        assertScript '''
+        // http://groovy.329449.n5.nabble.com/ConcurrentModificationException-with-use-of-memoize-tp5736788.html
+        
+        import java.util.concurrent.atomic.AtomicInteger
+        
+        class Utils { 
+            public static final AtomicInteger EXECUTION_COUNT = new AtomicInteger(0)
+        
+            public static final Closure powerSet =  { Collection things -> 
+                EXECUTION_COUNT.incrementAndGet()
+        
+                def Set objSets = things.collect { [it] as Set } 
+                def Set resultSet = [[] as Set] 
+                def finalResult = objSets.inject(resultSet) { rez, objSet -> 
+                        def newMemberSets = rez.collect { it -> (it + objSet) as Set } 
+                        rez.addAll(newMemberSets) 
+                        rez 
+                } 
+            }.memoize() 
+    
+            public static Collection combinations(Collection objs, int n) { (n < 1 || n > objs.size()) ? null : powerSet(objs)?.findAll { it.size() == n } } 
+        } 
+        
+        def threadList = (0..<10).collect {
+            Thread.start { 
+                Collection things = [
+                        [1, 2, 3],
+                        [1, 2],
+                        [1, 2],
+                        [2, 3],
+                        [2, 3],
+                        [3, 4],
+                        [3, 4],
+                        [5, 6, 7, 8]
+                ]
+                Utils.combinations(things, 2) 
+            } 
+        }
+        threadList << (0..<5).collect {
+            Thread.start {
+                def things = [
+                    [1, 2, 3],
+                    [1, 2, 3],
+                    [1, 2],
+                    [2, 3, 4],
+                    [2, 3, 4],
+                    [3, 4],
+                    [3, 4, 5],
+                    [5, 6, 7, 8]
+                ]
+                Utils.combinations(things, 2) 
+            }
+        }
+        
+        threadList*.join()
+        
+        assert 2 == Utils.EXECUTION_COUNT.get()
+        '''
+    }
+
     private static class ClassWithMemoizeClosureProperty {
         int timesCalled, timesCalledSoftRef
         def mc = {