Java synchronized method lock on object, or method?
When it comes to synchronized instance methods, they lock on the current object (this
). This essentially means no two threads can execute synchronized instance methods of the same object in parallel.
Example:
Meanwhile, synchronized static methods utilise the class object (ClassName.class
) as lock. So, no two threads can execute synchronized static methods of the same class simultaneously.
Example:
Simplified breakdown of the components involved
The dexterity of synchronized blocks
Synchronized methods lock at either object or class level. At times, you might want to lock specific portions of an object, hence synchronized blocks come to the rescue. You can use them to lock an individual resource within a method, thereby efficiently reducing the performance impact and avoid unnecessary wait time for threads.
The simplicity of atomic variables
When it comes down to counter variables, or similar tasks, opting for AtomicInteger or other analogous atomic classes can help skip the need for synchronization. These atomic variables offer thread-safe operations on single variables by utilising mechanisms like compare-and-set, which can help avoid the overhead associated with synchronization.
Choosing the appropriate tool
While deliberating synchronization, it's key to select the technique that matches your needs ideally. Keep in mind factors like complexity and size of the critical section, the anticipated concurrency level, and whether your need relates to immutable operations or complex inter-thread interactions.
Choosing between synchronized and atomic variables
Achieving thread safety with less overhead
When performing simple atomic operations, consider using atomic classes. They prove especially useful working with primitive numbers demonstrating better performance due to reduced locking overhead.
Maintaining consistency with synchronized
If your goal is maintaining consistency of values across variables or coordinating complex interactions between threads, then synchronized methods will serve you better. Upon exiting a synchronized method, a happens-before relationship is established, ensuring memory visibility and thus subsequent reads reflect the latest updates.
Avoid performance pitfalls using synchronized
Avoid extensive use of synchronized
as it can lead to suboptimal concurrency affecting performance. Remember, you're not just locking the method but potentially locking the object, leading to contention points and potentially slowing down your application.
Understanding the scope of locks and memory visibility
When to synchronize at instance level and when at class level
Recognising when to use synchronization at the instance level versus the class level is crucial. A static synchronized method locks on the class object, affecting all instances of that class, while an instance synchronized method locks on the specific instance.
Memory consistency impacts
Synchronization guarantees a happens-before relationship. Any thread entering a synchronized method or block sees all the modifications guarded by the same lock made prior to its entry.
Fine-grained locking practices
In some situations, using separate lock objects instead of this
or ClassName.class
, can provide a finer control on our program reducing contention among threads and hence improving scalability.
Was this article helpful?