Gpars (Groovy Parallel Systems) is the best solution for your concurrency problems with mutable objects.
Gpars gives you a number of high-level abstractions for writing concurrent and parallel code in Groovy (map/reduce,
fork/join, asynchronous closures, actors, agents, dataflow concurrency, and other concepts), which can make your Java
and Groovy code concurrent and/or parallel with little effort. Gpars is bundled in Groovy starting from version 2.1.
Recently, I had to write a script in Groovy that works with collections in multi-threaded mode. The best and easiest
way to safely and correctly manage mutable state within the Application is the Agent from the Gpars framework. Agent
completely encapsulates its internal state; the only way to pass messages to it is to use the method send(). You can also
use Groovy “<<” (leftShift) operator, or the implicit call() method, which uses the overridden send() method. To get the
stored value from the agent, you can use the val property. When you call the val property, the agent waits while all scheduled tasks are finished, and only then will the result be returned.
Agent agent = new Agent(new HashMap())
assert agent.val.size() == 0
agent.send {it.put("key","value")} // identical to: agent << { it.put("key","value")}
assert agent.val.size() == 1 // agent.val is executed only when all scheduled tasks are executed.An interesting feature is that you can send only code blocks (closures) but not the final result. The agent collects all
the jobs in the queue and executes them in order of receipt. For better understanding, consider such a
comparison: the agent is a workshop with a set of materials, the entrance to which is only by turn, so if you
want to do something with this material, you have to send the worker to take the place in the queue.
You can read more about Gpars in the official documentation
