17

I read somewhere that synchronized(this) should be avoided for various reasons. Yet some respectable code that I encountered uses the following in the constructor:

public SomeClass(Context context) {
  if (double_checked_lock == null) {
    synchronized (SomeClass.class) {
      if (double_checked_lock == null) {
        // some code here
      }
    }
  }
}

Is there really a difference between synchronized(this) and synchronized(SomeClass.class)?

Community
  • 1
  • 1
ef2011
  • 10,431
  • 12
  • 49
  • 67

6 Answers6

34

synchronized(this) is synchronized on the current object, so only one thread can access each instance, but different threads can access different instances. E.g. you can have one instance per thread.

This is typically useful to prevent multiple threads from updating an object at the same time, which could create inconsistent state.

synchronized(SomeClass.class) is synchronized on the class of the current object ( or another class if one wished) so only one thread at a time can access any instances of that class.

This might be used to protect data that is shared across all instances of a class (an instance cache, or a counter of the total number of instances, perhaps) from getting into an inconsistent state .

DNA
  • 42,007
  • 12
  • 107
  • 146
  • 2
    +1. This gives more clarity between class and object lock. I didn't found anything better than this. *Short and Simple to Understand* – Ravi May 21 '17 at 16:21
7

this is different for each instance.
ClassName.class is not.

Therefore, synchronized(this) will allow multiple instance to run simultaneously.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
3

The synchronized keyword, when applied to a class locks on the class, and when it's applied to this locks on the current object instance. From the Java Language Specification, section 8.4.3.6, 'synchronized Methods':

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.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
3

Each java Object can have a lock. This lock can be held by at most one thread at a time, any other thread has to wait to get the lock of the same object.

  • synchronized(this) acquires the lock of the instance this for the current thread. The method can run parallel on different instances (different values for this and therefore different locks)

  • synchronized(SomeClass.class) acquires the lock of the global class object of SomeClass. Only one instance of the method can run as all object instances lock on the same global object (same lock).

josefx
  • 15,506
  • 6
  • 38
  • 63
1

These are 2 different object to lock on: 'this' refer to current instance context, so creating multiple instances will have no effect if, for example, each thread using a different instance and lock on it. 'this' can be referred only on non-static context.
the 'class' is a static member of the Java Class and there is exactly one instance of it. You can lock on it in both static and non-static context.

1

synchronized(this) synchronizes on the instance of the object.

synchronized(SomeClass.class)uses the instance of the Class object that represents SomeClass, which is global for all instances in the same classloader.

Thus, these are different constructs with different semantics.

Using synchronized alone, or as a method modifier, also synchronizes on the instance's semaphore, which is normally used to prevent contention between multiple threads accessing that instance as a shared resource (i.e. a List).

The thread you refer states that it's a better practice to use a private instance, as synchronizing directly on your object instance may be dangerous. For that you'd use:

class MySharedResourceClass {

    private SomeClass lock = new SomeClass();

    public doSomething() {
        synchronized (lock) {
            // Do something here
        }
    }
}
jjmontes
  • 24,679
  • 4
  • 39
  • 51