Now that we know how object locking works, the next topic to understand is the lock scope. Just like variable scope, locks too have a scope. However, this can be understood only in terms of explicit locking using the concepts we learnt in the previous chapter on “Explicit Locking”
Since the lock() and unlock() method calls are explicit, we can move them anywhere, establishing any lock scope, from a single line of code to a scope that spans multiple methods and objects. By providing the means of specifying the scope of the lock, we can now move time-consuming and threadsafe code outside of the lock scope. And we can now lock at a scope that is specific to the program design instead of the object layout.
To put it simply, the lines of code between the lock() and unlock() methods is the scope of the lock that is being acquired.
It is possible for the synchronized keyword to lock a block of code within a method. It is also possible for the synchronized keyword to specify the object whose lock is grabbed instead of using the lock of the object that contains the method. Much of what we accomplish with the Lock interface can still be done with the synchronized keyword. It is possible to lock at a scope that is smaller than a method, and it is possible to create an object just so that it can be used as an synchronization object.
A Synchronized Block would look like below:
// lots of code
// Code to be synchronized
// lots more code
This syntax of the synchronized keyword requires an object whose lock is obtained. Here we are using the this object. Using this syntax, we can now lock individual lines of code instead of the whole method. We can also share data across multiple objects by locking on other objects instead, such as the data object to be shared.
After reading this chapter, you may be wondering “How different are Synchronized Methods from Synchronized Blocks?”
Well, the answer my friend is that, a synchronized method and block work the same way. The scope of the lock is the only difference. Using synchronized blocks, we can implement synchronization at a higher/granular level for only a few lines of code instead of the whole method. Apart from this, they work in exactly the same way.
Previous: Explicit Locking
Next: Choosing a Locking Mechanism