Can two threads execute the same synchronized block of code on the same object if they use different monitors?

Viewed 582

I'm newish to Java concurrency and I'm trying to better understand monitors.

Suppose I have one object, with a method that takes some kind of reference argument and uses that argument as a monitor in a synchronized block:

class Entity() {
    public void myMethod(Object monitor) {
        synchronized(monitor) {
            // critical stuff
        }
    }
}

Can two threads enter that section at the same time on the same entity if they use different objects for the monitor?

final Entity myEntity = new Entity();
for (int i = 0; i < 3; i++) {
    new Thread() {
        public void run() {
            // Can these all run concurrently?
            myEntity.myMethod(new Object());
        }
    }.start();
}

If I understand monitors correctly, then yes, all the threads can enter the synchronized block at the same time, because each monitor acts as a totally different mutex and none of the threads are aware of the other threads in that block.

It's been difficult to find documentation on this because tutorials mostly seem to just use "this" as the monitor.

1 Answers

Can two threads enter that section at the same time on the same entity if they use different objects for the monitor?

From the oracle tutorial one can read:

Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.

This informally means that one can synchronize using any Java Object. A block enclosed by a clause synchronized on a single object instance will be executed sequentially, i.e., executed by the thread holding the lock of the object being synchronized.

Can two threads enter that section at the same time on the same entity if they use different objects for the monitor?

Yes, multiple threads can execute (in parallel) the same code region wrapped with a synchronized clause as long as each of those threads is synchronizing using different object instances.

One can also synchronize using the class itself, rather than its instances:

 synchronized (SomeClass.class){
     System.out.println("Hello World");
 } 

In such cases, all the threads that use the clause synchronized on the class SomeClass, will have to synchronize among each other.

One can also use clause synchronized on methods (e.g., public synchronized void method2()); for non-static methods the object being synchronized will be the object to which that method belongs, whereas for static methods (e.g., public static synchronized void method1()) will be class itself to which that method belongs.

Related