Monday 30 January 2012

Synchronization pitfall

Synchronized method modifier is equivalent to block synchronized(this). Not only invoking of such methods is expensive for virtual machine, but they're also a little bit risky. Object's monitor can be taken not only during method invocation, but also by another object that has a reference to it.
Let's take a look at this example:
Class Resource contains some object and provides synchronized methods for fetching it.
getVeryImportantObject() has synchronized modifier.
getVeryImportantObjectWithMutex() uses synchronized block on private object.

We also have an evil class:
Cheater owns a reference to Resource and it blocks it in blockResource() method.

The class that glues it together:
Pitfall invokes 3 threads. The first one uses Cheater to take the monitor of created object of Resource class. Next threads start after 1 second in order to allow the first one performing its task. The second thread tries to get resource object by using method with synchronized modifier, however it never succeeds. The third thread grabs this object by using method with internal synchronized block.
Project Lombok provides an interesting way of not getting into this trap (http://projectlombok.org/features/Synchronized.html)

No comments:

Post a Comment