Question

In the below example, lock is obtained on instance variable employee (not on this), but still Threads of TestClass1 are getting locked while entering synchronized block. Any advice why is this behaviour. As far as my understanding it should get locked if its synchronization is on this.

public class TestClass{
  public static void main(String args[]){
    TestClass1 obj = new TestClass1();
    Thread t1 = new Thread(obj, "T1");
    Thread t2 = new Thread(obj, "T2");
    t1.start();
    t2.start();
  }
}

class TestClass1 implements Runnable{

Employee employee = new Employee();

public void myMethod () {
    synchronized (employee) {
        try {
            Thread.sleep(4000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void myOtherMethod() {
    synchronized (employee) {
        try {
            Thread.sleep(4000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

@Override
public void run() {
    myMethod();
    myOtherMethod();
}
}
Was it helpful?

Solution

You are using the same TestClass1 instance for both threads, therefore they are using the same Employee instance to lock on.

To get them to use different locks, you need to do:

Thread t1 = new Thread(new TestClass1(), "T1");
Thread t2 = new Thread(new TestClass1(), "T2");

OTHER TIPS

Both threads use the same instance of TestClass1. So internally they share the same employee instance. To avoid this create a new instance for each Thread.

You are using the same object (employee) for your synchronization. It means that indeed of one thread entered the synchronized block other thread will be locked until the first frees the lock. It does not matter whether you are using this or any other object. What does matter is that this is the same object.

This is the purpose of synchronization. If access to specific object should be synchronized because the data may be inconsistent if 2 or more threads use this data simultaneously we use synchronization.

What you are doing is creating a Runnbable object and making two Thread object out of it. Assigning two different names to the threads does not make them two threads and conversely, assigning same name to two threads does not make them one thread .

Basically, you are creating a duplicate thread with the same resources.

So, your first thread locks onto the employee and the second thread (which in reality is the same Runnable as the first that obtained the lock) requests a lock on employee. So, it gets blocked.

What is happening is that the Runnable is requesting a lock on itself.

Just do as Keppil suggested:

Thread t1 = new Thread(new TestClass1(), "T1");
Thread t2 = new Thread(new TestClass1(), "T2");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top