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 = {