Since Groovy 1.7.3 we have a new AST transformation: @Synchronized. This annotation is based on the Project Lombok Synchronized annotation. We can use the annotation on instance and static methods. The annotation will create a lock variable in our class (or we can use an existing variable) and the code is synchronized on that lock variable. Normally with the synchronized
keyword the lock is on this
, but that can have side-effects.
import groovy.transform.Synchronized class Util { private counter = 0 private def list = ['Groovy'] private Object listLock = new Object[0] @Synchronized void workOnCounter() { assert 0 == counter counter++ assert 1 == counter counter -- assert 0 == counter } @Synchronized('listLock') void workOnList() { assert 'Groovy' == list[0] list << 'Grails' assert 2 == list.size() list = list - 'Grails' assert 'Groovy' == list[0] } } def util = new Util() def tc1 = Thread.start { 100.times { util.workOnCounter() sleep 20 util.workOnList() sleep 10 } } def tc2 = Thread.start { 100.times { util.workOnCounter() sleep 10 util.workOnList() sleep 15 } } tc1.join() tc2.join()