ConcurrentModificationException with use of memoize

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

ConcurrentModificationException with use of memoize

donnoit
This post has NOT been accepted by the mailing list yet.
Hello all,

I have some Groovy code which is using a Closure with memoize(). This code is being called from inside a eachWithIndexParallel invocation.

GParsPool.withPool {
  ....
  buckets.eachWithIndexParallel {
     .....
       Utils.combinations( objectList, 2)
 }

class Utils {
        public static final Closure powerSet =  { Collection things ->
                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 } }
}

I randomly see ConcurrentModificationException stemming from the line of code where the Utils.combinations function is defined.  This seemed odd to me as the variables involved are all local.  However, if I get rid of the memoize and make the Closure into a simple function, it seems to fix the problem (can't seem to reproduce the CM exception anymore despite many tries) , but is not optimal as I'd really like to use the memoize here for performance reasons.

So I went looking and found that in 2014 someone else reported in this forum about a CME with closures and memoize:  http://www.groovy-lang.org/mailing-lists.html#nabble-td5719786

No definitive conclusion was found in that thread about the root-cause, except that the reporter avoided the problem by avoiding memoize.  Has any user or the Groovy maintainers gained any deeper insights since?
Would appreciate any pointers.

Thanks
Don


Reply | Threaded
Open this post in threaded view
|

Re: ConcurrentModificationException with use of memoize

Daniel Sun
Hi Don,

      I assume that it may be related to the cache based on Collections.synchronizedMap, the implementation is refined via using ConcurrentLinkedHashMap on parrot branch. Could you give it a try by following the steps?

$ git clone -b parrot https://github.com/apache/groovy.git
$ cd groovy
$ gradlew -PuseAntlr4=true jarAllAll
( then you can find the "groovy-all-2.5.0-SNAPSHOT.jar" file under directory target/libs )

     Good luck :)

Cheers,
Daniel.Sun
Reply | Threaded
Open this post in threaded view
|

Re: ConcurrentModificationException with use of memoize

Daniel Sun
In reply to this post by donnoit
Hi Don,

      I found the issue is related to another cache issue, so could you provide some runnable code to reproduce the issue? I'll set asside some time to investigate it.

Cheers,
Daniel.Sun
Reply | Threaded
Open this post in threaded view
|

Re: ConcurrentModificationException with use of memoize

Daniel Sun
In reply to this post by donnoit
Hi Don,

     The issue should be fixed in 2.5.0+(NOT included in 2.5.0-beta-3),
please reference the thread about jitpack to give it a try:

http://groovy.329449.n5.nabble.com/JitPack-for-Groovy-tp5747625.html

Cheers,
Daniel.Sun




--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html