Search

Dark theme | Light theme

June 27, 2010

Groovy Goodness: Synchronized Annotation for Synchronizing Methods

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