1

According to my understanding, every object has a lock that can be hold by the current thread.

So, based on this example:

public class T1 {
    private final Object o = new Object();

    public  void m1() {
        synchronized(o) {
            //...wait some time
        }
    }
}

If I create something like:

    T1 subject1 = new T1();
    T1 subject2 = new T1();
    Runnable r1 = new Runnable() {
        @Override
        public void run() {
            subject1.m1();
            subject2.m1();  
        }
    };

Thread t1 = new Thread(r1);
t1.start();

There will be two locks, subject1.o and subject2.o (I tested they are different instances), which means both methods will run independently and at the same time, well, in my example one is executed and then, after it releases the lock, the next runs although subject1 and subject2 are different instances with different locks.

Why?

4
  • Both subject1 and subject1 are instances of T1 extends Object, therefore, if you apply lock on object by calling synchronize, they will process in order of lock acquiring... Commented Dec 10, 2018 at 17:29
  • But each instance contains its own lock, doesn't it? So, why the behaviour looks like they share the same lock? Commented Dec 10, 2018 at 17:30
  • They extend same object on which both put right to lock. Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class. Therefore if subject1 acquired lock on Object, it won't allow others to access it( synchronize takes care of that ) until it finishes it's work. Commented Dec 10, 2018 at 17:32
  • Ok, both classes extend Object, but talking at instance level, both Object parent's class are also different. If you're talking at Class level, then any other instance of any other object would be locked as well. The point here is why even with different instances of T1, they block each other given they have different lock object instances. Commented Dec 10, 2018 at 18:47

3 Answers 3

2

In your example, you are running the two method sequentially in the same thread. To execute them in parallel, you must run them in separate threads.

T1 subject1 = new T1();
T1 subject2 = new T1();
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        subject2.m1();  
    }
};
Runnable r2 = new Runnable() {
    @Override
    public void run() {
        subject2.m1();  
    }
};

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
Sign up to request clarification or add additional context in comments.

1 Comment

@Eduardo, the locks are not blocking each other in your example. They are simply running the first method to completion before the second method begins executing.
1

There will be two locks, subject1.o and subject2.o ..., which means both methods will run independently and at the same time.

No. The fact that there are two locks does not mean that two calls to the m1 function will run independently and at the same time. It only means that two calls can run at the same time. But that can only happen if each of those two calls happens in a different thread.

What other answers here have already tried to tell you is, your code doesn't make the two calls from two different threads. It makes both calls from the same thread. You wrote this run() method:

public void run() {
    subject1.m1();
    subject2.m1();  
}

There's nothing special about a run() method. YOU wrote it, and it will work exactly like any other method that you write: The one that you wrote will first call subject1.m1(), and then when that returns, it will call subject2.m1().

If you want to make those calls in parallel, then do what @Palamino or @snr showed you.

Comments

1

There will be two locks, subject1.o and subject2.o (I tested they are different instances), which means both methods will run independently and at the same time

You say both methods will run independently though you have only one enclosing method to run both threads. Instead, both methods have to be within different Runnables to be executed concurrently.

T1 subject1 = new T1();
T1 subject2 = new T1();
Runnable r1 = subject1::m1;
Runnable r2 = subject2::m1;
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.