I often find myself with code like
private static final MyType sharedResource = MyType();
private static final Object lock = new Object();
...
synchronized(lock)
{
//do stuff with sharedResource
}
Is this really neccessary or could sharedResource be used as the lock itself like
private static final MyType sharedResource = MyType();
...
synchronized(sharedResource)
{
//do stuff with sharedResource
}
Note: synchronized blocks shown in the examples would live within methods doing work and are not methods themselves or synchronized methods.
EDIT: A very good point has been pointed out in some of the answers that if we are dealing with multiple shared resources that the first “Object” technique is far safer.
WARNING The fact that sharedResource is static is important! If it is static then synchronized methods or synchronized blocks locking on this won’t work. The lock object must also be static.
Pros and cons of both
First option pros: Allows locking on concept, not on Objects. If you had to lock on multiple resources for a single action (which is usually not advised, but sometimes necessary) you could do this with much less worry about race conditions.
cons: The object could still be modified, so you need to ensure access to the object is restricted to methods that abide by the external lock.
Second option pros: Lock on the object should prevent others from modifying it (although you should double check the exact symantics.) EDIT: Has the same con as above – if the methods aren’t
synchronizedinternally, you could still run into methods that don’t abide by the contract.cons: You block access to all methods, even those unrelated to what you’re trying to operate, which could cause slowdowns and possibly deadlock. You could easily make the case, however, that if that’s the case your Object is doing too much work and should be broken up.
EDIT: Allow me to clarify part 2 here (the case to break up MyType into MyFoo and MyBar is open for debate…)
Personally, I use option 1 much more often (that’s why I’m unsure about that part in option 2).