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()