Java concurrency
synchronized methods
multithreading
concurrent programming
method synchronization

If I synchronized two methods on the same class, can they run simultaneously?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

In the realm of concurrent programming in Java, understanding synchronization is crucial to ensuring the correct functioning of applications. One common point of confusion pertains to synchronizing methods within a class: if two methods are synchronized on the same object, can they execute concurrently?

Understanding Java Synchronization

Java provides the synchronized keyword to control access to methods or blocks of code that are critical sections, meaning they should not be accessed by more than one thread at a time. Synchronization in Java is based on monitors or intrinsic locks. Every object in Java has an intrinsic lock associated with it, and a thread needs to obtain this lock to enter a synchronized block or method.

Key Concepts

  • Synchronized Methods: When you declare a method as synchronized, the thread invoking this method must acquire the intrinsic lock associated with the object owning the method.
  • Lock Contention: If one thread holds the lock, other threads attempting to enter any of the object's synchronized methods will block until the lock is released.
  • Atomicity and Visibility: Synchronization ensures that a method or block of code is executed atomically, and it also ensures memory visibility so that changes made in one thread are visible to others.

Can Two Synchronized Methods Run Concurrently?

Same Object Synchronization

When two methods are synchronized on the same object (typically the instance), the rule is straightforward:

  • If both methods are instance methods and are synchronized on the same object (the current instance or this), they cannot run simultaneously.

The intrinsic lock acquired on entering a synchronized method is the same lock released on exiting the method. Thus, if one method holds the lock, another method that attempts to acquire the same lock must wait.

java
1public class SharedResource {
2
3    public synchronized void method1() {
4        // Critical section
5        System.out.println("Executing Method 1");
6        try {
7            Thread.sleep(1000); // Simulate work
8        } catch (InterruptedException e) {
9            Thread.currentThread().interrupt();
10        }
11    }
12
13    public synchronized void method2() {
14        // Critical section
15        System.out.println("Executing Method 2");
16        try {
17            Thread.sleep(1000); // Simulate work
18        } catch (InterruptedException e) {
19            Thread.currentThread().interrupt();
20        }
21    }
22}

In this setup, if method1() is executing, method2() cannot start, as both require the same lock.

Different Object Instances

Synchronized methods in different instances of the same class do not interfere with each other. Each object has its own intrinsic lock.

java
1SharedResource instance1 = new SharedResource();
2SharedResource instance2 = new SharedResource();
3
4Thread t1 = new Thread(instance1::method1);
5Thread t2 = new Thread(instance2::method2);
6
7t1.start();
8t2.start();

Here, each thread is working with a separate instance, allowing concurrent execution of method1() on instance1 and method2() on instance2.

Static Synchronization

Static methods synchronize on the class object, not the instance. Thus, all static synchronized methods in a class can block each other:

java
1public class StaticSyncExample {
2
3    public static synchronized void staticMethod1() {
4        // Critical section
5        System.out.println("Executing Static Method 1");
6    }
7
8    public static synchronized void staticMethod2() {
9        // Critical section
10        System.out.println("Executing Static Method 2");
11    }
12}

Static methods staticMethod1() and staticMethod2() use the class object to synchronize, so they can't run simultaneously.

Summary Table

ConditionConcurrent Execution Allowed?
Same instance, two synchronized methodsNo
Different instances, methods on eachYes
Static synchronized methods on a classNo

Additional Considerations

  • Reentrant Lock: Java also provides java.util.concurrent.locks.ReentrantLock as an alternative to intrinsic locks for more advanced control over synchronization.
  • Performance Considerations: Overuse of synchronization can lead to performance bottlenecks due to increased contention.
  • Read vs. Write Locks: For collections or shared data that may involve frequent reads and infrequent writes, java.util.concurrent.locks.ReadWriteLock can improve performance.

In conclusion, understanding how synchronization works in Java is key to developing robust multithreaded applications. Synchronizing methods carefully and understanding the implications can prevent several concurrency issues like race conditions and deadlocks.


Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions