Difference between class locking and object locking in Java

xploreraj picture xploreraj · Apr 24, 2014 · Viewed 18.8k times · Source

People tell about two types of multi-threaded locking - object and class. In my knowledge, locking is done on objects only.

Case 1: On objects we create using new or factory methods etc.

void synchronized myMethod(Type param) {
  //will lock on the instance used to call this method
}

or

synchronized(this) {
 //will lock on current object
}

or

synchronized(obj1) {
 //will lock on specified obj1 object
}

Case 2: On java.lang.Class objects

This is called class lock, and can be used with static fields or methods or blocks, as they belong to class and shared among all the objects, and other class properties.

static void synchronized method() {
  //will lock the Class object
}

or

static {
  synchronized(SomeClass.class){
    int a = 2;
  }
}
  • Why I am thinking this also as an object locking because classes are loaded into the Method Area in the JVM, and all the static properties of the class are wrapped inside a java.lang.Class object created by JVM. So behind abstraction, its object locking and in the picture, we see Class locking.
  • So I can also infer one more thing. Just as objects locked by a thread can not be acquired by another thread as long as it is not released by first thread, class locking (the java.lang.Class instance) also works in same manner.
  • I want to know in case of synchronized static methods, lock on which class is acquired by the thread in following two cases:

    1. This method is called from same class where it is defined.
    2. This method is called from derived class with derived class name.

This is my understanding so far regarding the subject. Please add on or rectify.

Answer

Solomon Slow picture Solomon Slow · Apr 24, 2014

People tell about two types of multi-threaded locking - object and class.

A Class is an Object. There is only one kind of locking in the Java language: Every Object (including every Class) has a mutex that can be locked by a synchronized block or a synchronized method. The Object to be locked is implicit in a synchronized method: It's the "this" instance for an instance method, and it's the Class object for a static method.

One of the most common newbie mistakes is to think that two different threads can't get into the same synchronized block at the same time. They can, and there's plenty of questions and answers here in StackOverflow that prove it. Another mistake is to think that if one thread is synchronized on some object, then other threads will not be able to modify the object. They can and they do.

Synchronization prevents two or more threads from synchronizing on the same Object at the same time. Which object is the right object? It's all about protecting your data. If the structure that you want to protect is a linked list, for example, then a good choice would be for any method that accesses the list to synchronize on the list header. If you want to protect global data (e.g., static variables), then you want to synchronize on a global object (e.g., the Class object that owns the variables.) The important thing is that, if you have read/write data (a.k.a., "mutable data") that are accessed by more than one thread, then every method that accesses the same data must synchronize on the same lock.


There is another kind of locking in Java, but it's not in the Java language; it's in the Java standard library. It's available through objects that implement the java.util.concurrent.locks.Lock interface. Of course a Lock object (like any Object) also implements the first kind of locking, but you should never, ever, synchronize on a Lock object unless you want to give people the impression that you are a clueless newbie.

The java.util.concurrent-style locking is more powerful than using synchronized blocks because of it's explicit lock() and unlock() methods. For example, it is possible for one method to lock a lock, and a different method to unlock it. That can lead to code that is tricky to understand, and I wouldn't do it unless I had a very good reason, but sometimes there are good reasons.