Simplified Use of Locks in Groovy
I am currently writing an article about the challenges and pitfalls of concurrent programming for a German software magazine. Since the magazine's readers come from all kinds of platforms and programming languages I've chosen Groovy as a concise means to present my examples. Groovy - together with its associated library GPars - comes with good support for easy synchronization and locking (e.g. @WithReadLock, @WithWriteLock and @Synchronized). However, I do not want to introduce the concept of AST transformations so I came up with a new way of using locks in Groovy - originally motivated by Chris Broadfoot. Here's a short example:
class Shelf {
final products = []
final lock = new ReentrantLock()
void putIn(Product product) {
lock {
if (isFull())
throw new StorageException("shelf is full.")
products << product
}
}
boolean takeOut(Product product) {
lock {
return products.remove(product)
}
}
}
It looks like lock was a new keyword but actually I achieved that with a tiny bit of Groovy meta programming:
Lock.metaClass.useFor = { Closure operation ->
lock()
try {
operation()
} finally {
unlock()
}
}
Lock.metaClass.call = { Closure operation ->
delegate.useFor(operation)
}
Now that I used it in a couple of examples I suggest it should be considered for inclusion in GDK. What do YOU think?
P.S.: Don't get me wrong about the usefulness of explicit locking. In most cases other concepts - like parallel collections, data flows and agents - should be preferred.
Leave a comment