Abhendra Singh
Abhendra Singh

Reputation: 1957

Class Lock And Object Lock In Multithreading

I tried an interview question with static functions and non static functions as synchronized and one function was non synchronized. As in below code:

public class Resource {

public static synchronized void m1() throws InterruptedException {
    System.out.println("Entering m1 method");
    Thread.sleep(10000);
    System.out.println("Leaving m1 method");
    System.out.println();
}

public synchronized void m2() throws InterruptedException {
    System.out.println("Entering m2 method");
    Thread.sleep(2000);
    System.out.println("Leaving m2 method");
    System.out.println();
}

public void m3() throws InterruptedException {
    System.out.println("Entering m3 method");
    Thread.sleep(2000);
    System.out.println("Leaving m3 method");
    System.out.println();
}

public synchronized void m4() throws InterruptedException {
    System.out.println("Entering m4 method");
    Thread.sleep(2000);
    System.out.println("Leaving m4 method");
    System.out.println();
}

}

public class ThreadDemo {

public static void main(String[] args) {

    final Resource resource = new Resource();

    Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                resource.m1();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    });

    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                resource.m2();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    });

    Thread t3 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                resource.m3();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    });

    Thread t4 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                resource.m4();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    });

    t1.start();
    t2.start();
    t3.start();
    t4.start();
}

}

Here four threads are created.

  1. T1 is calling static synchronized(m1)
  2. T2, T4 are calling synchronized(m2, m4) and
  3. T3 is calling non synnchronized(m3).

It's output is:

Entering m1 method
Entering m3 method
Entering m2 method
Leaving m3 method

Leaving m2 method

Entering m4 method
Leaving m4 method

Leaving m1 method

My question is:

1) static synchronized method make class level lock. Here what is the meaning of class level locking? If one thread has taken lock and class level lock is occupied then why thread T2 and T3 starts execution?

2) T4 is waiting to complete T2. Although synchronization is applied on two different methods, then why T4 has to wait? If object level lock is working in T2, T4 then in above point why class level locking is not working?

Upvotes: 0

Views: 940

Answers (2)

Ravindra babu
Ravindra babu

Reputation: 38910

Regarding your queries:

1) static synchronized method make class level lock. Here what is the meaning of class level locking? If one thread has taken lock and class level lock is occupied then why thread T2 and T3 starts execution?

in case of static synchronized methods, only one thread acquire lock on these methods among multiple instances of class. If you have two different instances : resource1 and resource2 for Resource class, only one thread will succeed in getting lock on m1().

if resource1.m1() method execution is in progress by one thread, other thread can't execute resource2.m1() unless first thread finish the execution of m1().

Since method m3() is non-synchronized method, any thread can invoke this method without wait and getting lock.

Since both m2() and m4() are synchronized, only one thread will succeed in getting lock on same object ( resource in your example). Other thread has to wait until first thread completes the execution of synchrnozied method and release object level lock.

2) T4 is waiting to complete T2. Although synchronization is applied on two different methods, then why T4 has to wait?If object level lock is working in T2, T4 then in above point why class level locking is not working?

synchronized methods:

Making these methods synchronized has two effects:

  1. First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

  2. Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.

static synchronized methods:

The thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.

Upvotes: 0

Sergei Rybalkin
Sergei Rybalkin

Reputation: 3453

  1. Static method synchronization is an equivalent for

    public static void m1() {
        synchronize (Resource.class) {
        ...
        }
    }
    
  2. Non-static method synchronization is an equivalent for

    public void m2() {
        synchronize (this) {
            ...
        }
    }
    

Now if you will have a look where this is using as monitor and where Resource.class object is using as monitor everything should become clear.

A synchronized block in Java is synchronized on some object. All synchronized blocks synchronized on the same object can only have one thread executing inside them at the same time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.

In your case there are two objects. So, this rule is applicable for each object, but not to both.

Upvotes: 2

Related Questions