1

I'm new to Java concurrency and I know that an instance method synchronized means that only one thread can execute that method at a time. But does this thing depends on the monitor object or not? Could 2 threads execute the same synchronized instance method in the same time if the monitor object is different?

Ex: This is an example but I'm not sure if it's a good one. I just want to know if it is possible to call a synchronized method or block by two or more threads simultaneously. Or always a synchronized method cannot be called by

public class SynchronizedExchanger {

    protected Object object = null;

    public synchronized void setObject(Object o) {
        System.out.println("Do something, o = " + o);
        this.object = o;
    }
}

public class SynchronizedExchangerMainDemo {
    public static void main(String[] args) {
        SynchronizedExchanger exchanger = new SynchronizedExchanger();
        SynchronizedExchanger exchanger1 = new SynchronizedExchanger();

        Thread thread1 = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 1000; i++) {
                            exchanger.setObject("" + i);
                        }
                    }
                }
        );

        Thread thread2 = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 1000; i++) {
                            exchanger1.setObject("" + i);
                        }
                    }
                }
        );

    }
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
elvis
  • 956
  • 9
  • 33
  • 56
  • 1
    Add some code to your question so that one can understand your requirements precisely. Also, keep your question focused. Hopefully [this post](https://stackoverflow.com/q/3047564/10819573) answers your questions. – Arvind Kumar Avinash Aug 21 '23 at 10:13
  • Java Language Specification [8.4.3.6. synchronized Methods](https://docs.oracle.com/javase/specs/jls/se20/html/jls-8.html#jls-8.4.3.6): "A synchronized method acquires a monitor (§17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used." - that means: (i) a static synchronized method cannot be executed by 2 threads; (ii) a non-static synchronized method on the same instance, cannot be executed by 2 threads – user16320675 Aug 21 '23 at 10:49
  • 2
    --> "*monitor object is different*": yes, 2 threads can run the same instance method on two different instances (always true for any method or synchronized block on **different** monitors) || (BTW after edit (added code): code is doing nothing since threads are not being started - otherwise, both would run independently of each other) – user16320675 Aug 21 '23 at 10:57

3 Answers3

1

If an instance method is declared as synchronized, this means it's implicitly synchronized on this, so by definition the monitored object will be identical, and only one thread can execute the method at a given time.

If the method is not declared as synchronized, but instead you use an explicit synchronized block, only using the same monitor object will prevent concurrent execution. If two threads use different monitor objects, they can execute concurrently.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • additionally, if the method is `static`, there is no `this`, the synchronization is on the `Class` of the object containing that method (even if not relevant for the question, but maybe reader needs to know that) – user16320675 Aug 21 '23 at 10:53
  • @Mureinik thank you! I just want to know if 2 threads could execute a synchronized method simultaneously if monitor object is different, for example in the example that I have – elvis Aug 21 '23 at 10:59
  • @elvis In the example you added, the method is `synchronized`. `exchanger.setObject` uses the `exchanger` instance as a monitor, and similarly `exchanger1.setObject` uses the `exchanger1` instance, so the two threads won't block each other. – Mureinik Aug 21 '23 at 11:59
1

In your example code, exchanger and exchanger1 refer to two distinct instances. The two threads absolutely can call setObject "at the same time," because setObject is synchronized on this, and this refers to the exchanger instance in one thread, but it refers to the exchanger1 instance in the other thread.

synchronized(o) only prevents multiple threads from synchronizing on the same object o at the same time. And when you write:

synchronized MyType mymethod(...) {
    doSomeStuff(...);
    return something;
}

That's just a shortcut for:

MyType mymethod(...) {
    synchronized(this) {
        doSomeStuff(...);
        return something;
    }
}

It would be different if there was only one SynchronizedExchanger instance, and both threads were operating on it. In that case, this would refer to the same object in both threads, and the two threads would never both be allowed to be synchronized on it at any moment time.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
1

The monitor is the mutex, it is the thing a thread acquires in order to get exclusive access to the synchronized code. For instance methods the monitor is on the object instance, for static methods the monitor is on the class object.

So if two threads aren't acquiring the same monitor, neither is keeping the other thread out.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276