0

I'm trying to understand the exact differences in synchronisation using:

  1. synchronized(MyClass.class){...}

  2. synchronized(myClassInstance.getClass()){...} [edited as MyClass.getClass() doesn't even compile]

  3. synchronized(this){...}

Thanks to other posts I get that (1) is used to make sure that there is exactly one thread in the block and that (3) ensures that there is exactly one thread per instance.

(see Java Synchronized Block for .class )

But what does (2) do? Is it identical to (3)?

5
  • 4
    (1) Synchronizes on the Class, (2) Doesn't compile: you are using an instance method in a static context, (3) Synchronizes on the instance. Commented Aug 14, 2018 at 10:33
  • #2 would work if you would write myClassInstance, but in that case it would be identical to #1; the class is just referenced differently (that is, if myClassInstance is not an instance of a derived class instead of the base class). Commented Aug 14, 2018 at 10:39
  • #2 could also at least compile with MyClass.class.getClass(), couldn't it? Commented Aug 14, 2018 at 10:40
  • @Clijsters No, that would be the class of a class instance, which would probably be the same for any class (class java.lang.Class of course). Well, it would work: it would lock the same way as #1 I presume, but setting a lock on something that is not local is not recommended. Commented Aug 14, 2018 at 10:47
  • I just did it and it compiled. As you edited your comment: I just said it would compile, not it would make sense, nor that it's recommended ;) Commented Aug 14, 2018 at 10:47

2 Answers 2

1

You mention you already understand options #1 and #3 so I'll focus on option #2.

As I state in the question comments, option #2 doesn't compile as written. However, I believe your intent is to obtain the class in an instance fashion rather than a static fashion (MyClass.class).

public class MyClass { public void foo() { synchronized (MyClass.class) { } } public void bar() { synchronized (getClass()) { } } } 

In the above code both MyClass.class and getClass() return the same object which means they are "equivalent". However, you have to be careful here.

public class MySubClass extends MyClass { // inherits methods... } 

Now the two methods (foo and bar) are not equivalent. The method foo still uses the Class of MyClass to synchronize but bar now uses the Class of MySubClass (i.e. they are no longer synchronizing on the same object).

Sign up to request clarification or add additional context in comments.

Comments

0

Point 1 will take the lock on the Class Object and only one object can exists (if the same class is not loaded by different classloaders ) in the JVM. This can be used with Static as well as noon static methods

Second option will not compile.

Third Option will take the locks on the current object. Third option can be used with instance method as this can be used in case of static methods.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.