Object level lock vs Class level lock in Java

In Java, a synchronized block of code can only be executed by one thread at a time. Also, java supports multiple threads to be executed concurrently. This may cause two or more threads to access the same fields or objects at same time.

Synchronization is the process which keeps all concurrent threads in execution to be in sync. Synchronization avoids memory consistence errors caused due to inconsistent view of shared memory. When a method is declared as synchronized; the thread holds the monitor or lock object for that method’s object. If another thread is executing the synchronized method, your thread is blocked until that thread releases the monitor.

Please note that we can use synchronized keyword in the class on defined methods or blocks. synchronized keyword can not be used with variables or attributes in class definition.

1. Object level lock in Java

Object level lock is mechanism when we want to synchronize a non-static method or non-static code block such that only one thread will be able to execute the code block on given instance of the class. This should always be done to make instance level data thread safe.

Object level locking can be done as below :

public class DemoClass
{
	public synchronized void demoMethod(){}
}

or

public class DemoClass
{
	public void demoMethod(){
		synchronized (this)
		{
			//other thread safe code
		}
	}
}

or

public class DemoClass
{
	private final Object lock = new Object();
	public void demoMethod(){
		synchronized (lock)
		{
			//other thread safe code
		}
	}
}

2. Class level lock in Java

Class level lock prevents multiple threads to enter in synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads.

Class level locking should always be done to make static data thread safe. As we know that static keyword associate data of methods to class level, so use locking at static fields or methods to make it on class level.

public class DemoClass
{
	//Method is static
	public synchronized static void demoMethod(){

	}
}

or

public class DemoClass
{
	public void demoMethod()
	{
		//Acquire lock on .class reference
		synchronized (DemoClass.class)
		{
			//other thread safe code
		}
	}
}

or

public class DemoClass
{
	private final static Object lock = new Object();

	public void demoMethod()
	{
		//Lock object is static
		synchronized (lock)
		{
			//other thread safe code
		}
	}
}

3. Object level lock vs class level lock – Important notes

  1. Synchronization in Java guarantees that no two threads can execute a synchronized method, which requires same lock, simultaneously or concurrently.
  2. synchronized keyword can be used only with methods and code blocks. These methods or blocks can be static or non-static both.
  3. When ever a thread enters into Java synchronized method or block it acquires a lock and whenever it leaves synchronized method or block it releases the lock. Lock is released even if thread leaves synchronized method after completion or due to any Error or Exception.
  4. Java synchronized keyword is re-entrant in nature it means if a synchronized method calls another synchronized method which requires same lock then current thread which is holding lock can enter into that method without acquiring lock.
  5. Java synchronization will throw NullPointerException if object used in synchronized block is null. For example, in above code sample if lock is initialized as null, the “synchronized (lock)” will throw NullPointerException.
  6. Synchronized methods in Java put a performance cost on your application. So use synchronization when it is absolutely required. Also, consider using synchronized code blocks for synchronizing only critical section of your code.
  7. It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because they lock on different object.
  8. According to the Java language specification you can not use synchronized keyword with constructor. It is illegal and result in compilation error.
  9. Do not synchronize on non final field on synchronized block in Java. because reference of non final field may change any time and then different thread might synchronizing on different objects i.e. no synchronization at all.
  10. Do not use String literals because they might be referenced else where in the application and can cause deadlock. String objects created with new keyword can be used safely. But as a best practice, create a new private scoped Object instance OR lock on the shared variable itself which we want to protect. [Thanks to Anu to point this out in comments.]

Let me know thoughts and queries on Object level lock vs Class level lock in Java.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

69 thoughts on “Object level lock vs Class level lock in Java”

  1. point no 7. It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because they lock on different object.

    If a thread takes monitor on static synchronized method, it takes the lock on the Class level itself. Will the above sentence still be valid then ? How can both simultaneously run then ?

  2. Thanks for the nice content.in the below section of your code snippet

    public class DemoClass
    {
        public void demoMethod()
        {
            //Acquire lock on .class reference
            synchronized (DemoClass.class)
            {
                //other thread safe code
            }
        }
    }
     

    i think in this class level locking static is missing

  3. What is the difference between the following codes:

    public void increment()
    {
    synchronized(this)
    {
    }
    }

    class MultiThreading
    {
    Object lock= new Object();

    public void increment()
    {
    synchronized(lock)
    {
    }
    }

    }

    • Not any major difference. Both helps in instance level locking. Just make sure you do not leak the reference to lock variable (so no other thread can acquire lock through it) and you do not accidentally reinitialize the variable (make it final).

  4. Well explained, i’ve a doubt in object lock that is what is the difference between synchronizing a method code block with “this” keyword and synchronizing by creating a lock object. For example how does it makes a difference from execution point of view if we write like

    public void someMethod(){
              synchronized(this){
              //some code
              }
    }
    

    and

    public void someMethod(){
              Object lock = new Object();
              synchronized(lock){
              //some code
              }
    }
    
    • Well, technically there is no difference. Both do the same thing.
      Real difference lies in possibility of misuse. In above code, “lock” variable in known to your class and even method only, so chance of any abuse. this represents the object instance which other classes can access and decide to take lock on. It’s highly unlikely, but not impossible. It can cause your class to perform poorly under concurrent usage because there are other threads as well using the lock object.

      • so this way(synchronized(lock)) you can just lock for one operation only, rest of the operations are accessible for the instance , another acquire lock on instance level

  5. Point number 9 says:
    “9. Do not synchronize on non final field on synchronized block in Java. because reference of non final field may change any time and then different thread might synchronizing on different objects i.e. no synchronization at all.
    Best is to use String class, which is already immutable and declared final.”

    What do you mean by:
    “Best is to use String class, which is already immutable and declared final.”

    Do mean this:

    private String str = "abc";
    synchronized(str){ 
    //code here...
    }
    

    which is wrong i guess.

    OR this:

    synchronized(String.class){ 
    //code here...
    }
    

    Which will work for any class, why only String?

          • I replied to what it means. Seems that is not enough so to answer more, we should be using :

            private final String str = new String("ABC"); //Edited
            
            synchronized(str){ 
            
            //code here...
            
            }
            
          • its wrong to use string for lock as it is possible same literal in string pool used somewhere else and it will having lock on this you can get lock for somewhere else, its not right design wise.

          • String s = new String(“Test”);

            does not put the object in String pool , we need to call String.intern() method which is used to put them into String pool explicitly. its only when you create String object as String literal e.g. String s = “Test” Java automatically put that into String pool.

          • Hi Varun, how you think the argument string “test” is handled by JVM? For me, it’s a string literal passed as argument to an string object. As soon as, runtime seems string literal, it put in in pool.

  6. “if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads.”
    above statement is contradictory of waat point 7 says- “It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because they lock on different object”.
    please clear it.

    • Infact, they are not. First statement talk about class level locking. Second statement is talking a scenario where class and thread, BOTH level locking is used. If you think, I have not understood your question correctly, please elaborate more.

  7. Hello Lokesh,

    I am having an object of a class having some state.
    This object has two methods (m1() and m2()), both are changing the state of obj.
    m1() is synchronized but m2 is not synchronized.

    Now two threads, T1 and T2 approach obj
    ->T1 calls m1() which is synchronized
    -> T2 calls m2() which is not synchronized.

    What is found with my test results that the m2() was executing happily even though m1() had a lock. But I thought that if lock is acquired on the entire obj by putting sync on method then how any other method can be executed. It should wait.

    Your opinion is highly appreciated.

    Thanks & Regards,
    sn5816

      • class Customer implements Runnable {
        	
        	
        	account ac=new account();
        		public void run(){		
        			printWelcomeMessage();
        			makewithdrawl(1210);
        			
        			}
        			
        		
        		public  static void printWelcomeMessage()
        		{
        			System.out.println("Welcome "+Thread.currentThread().getName());
        		}
        	
        	public    void makewithdrawl(int amount)
        	{
        	synchronized(Customer.class)
        	{
        			System.out.println(Thread.currentThread().getName());
        			System.out.println("Available balance -------------- "+account.getbalance());
        		
        			System.out.println("  withdrawing the amoutn");
        			account.withdraw(amount);
        			System.out.println(" completed "+"Available balance is "+account.balance);
        	
        		
        	}	
        	}
        

        IN the above program consider that thread n is making a transaction and it is in middle. If (n+1) thread appears it have to wait for welcome method until the transaction of (n)is completed. Is there a way that we lock only the particular function during synchronization.???
        Thanks!! for examplanation .@sn5816. If there are any errors in my code please be with patience. I am new to java. 🙂

  8. ===================================How to lock Object===================================
    class A
    {
    synchronized void test1()
    {
    for(int i=0;i<100;i++)
    {
    System.out.println(i);
    }
    }
    synchronized void test2()
    {
    for(int i=200;i<300;i++)
    {
    System.out.println(i);
    }
    }
    }
    class B extends Thread
    {
    A a1;
    B(A a1)
    {
    this.a1=a1;
    }
    public void run()
    {
    a1.test1();
    }
    }
    class C extends Thread
    {
    A a1;
    C(A a1)
    {
    this.a1=a1;
    }
    public void run()
    {
    a1.test2();
    }
    }
    public class Manager1
    {
    public static void main(String[] args)
    {
    A a1=new A();
    //A a2=new A();
    B b1=new B(a1);
    C c1=new C(a1); //Here is chance to currpt the data because same references
    b1.start(); //If not same ref then no chance to currpt data
    System.out.println("============");
    c1.start();
    }
    }

  9. Hi Lokesh,
    I have always seen class level locking in my coding but never have i come across a requirement where i require an object level lock.Can you please tell me any real life scenario where we can use Object Level locking?

  10. Hi Sir,
    Really nice article, but i have doubt over one point can u pls elaborate it with example…
    7. It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because they lock on different object.

    • Hi,
      I would like to elaborate on you 7th point. As far as static synchronized methods are concerned, we are not taking any object into consideration as all static methods are class methods and can only be invoked by class variables. So, we can only have class lock on static methods.

      Now, for non static synchronized methods, we are talking about object only as these methods invoke on object. So, here we can have class locks as well as objects locks.

      So, two methods one is static and other is non static can take lock on object and class. In this way both the methods can run simultaneously.
      Hope this thing is clear to you.

      Thanks

      • here is the doubt….once the class is locked due to a thread holding monitor, how come other threads are getting access of the instances. Shouldn’t they be blocked too ?
        For class Lock – Say 10 threads are working, if 1 gets blocked – rest 9 gets blocked

        If yes – > Then how come they can run concurrently
        If No – > Why ?

  11. Hi Lokesh,

    Thanks for the article on synchronization. I liked it ..But I have query in my mind that . you said Synchronization method will allow lock on OBJECT level and by adding static synchronization it add the functionality to allow lock on CLASS level..

    But in the below code i have created 2 OBJECTS of same class but still i am not getting the desired effect of synchronization block .. but when i applied static to it hen it was working.. Please explain..

    Thanks in advance…

    public class Thread3 extends Thread 
    {
        //synchronized public void testsync()
        synchronized public static void testsync()
        {
            for (int i = 0; i &lt;= 5; i++) {
                System.out.println(i);
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }
    
    public void run() {
        testsync();
    }
    
    public static void main(String[] args) {
        Thread3 obj = new Thread3();
        Thread3 obj2 = new Thread3();
        obj.start();
        obj2.start();
    }
    }
    • I executed the above program. Below are the outputs:
      When method is static: 0 1 2 3 4 5 0 1 2 3 4 5
      When method is non-static: 0 0 1 1 2 2 3 3 4 4 5 5

      When method is static: class level lock i.e. both instances of Thread3 are locked by first obj and then obj2. They execute the method in sequence.
      When method is non-static: Both instances execute the method independently in their instances.

      In fact, in non-static mode they do not share any shared resource/method. So if you drop the synchronized keyword itself, it doesn’t make any difference.
      synchronized keyword should be used to protect some shared resource which will be accesses simultaneously by multiple threads. Here testSync() method does not do anything like that.

  12. Hi Lokesh,

    Thanks for you articles, they are great!!

    I would like to mention one thing though that your explanation on Class Level Lock is bit misleading:

    “Class level locking prevents multiple threads to enter in synchronized block in any of all available instances on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads. This should always be done to make static data thread safe.”

    Static code doesn’t belong to any instance, so it has no relation with instances at all. Yes out of 100 threads contending only one thread having managed to acquire the class level lock will be able to execute the static block of code.
    This should be enough, as code block belongs to instances (non-static methods) can still be executed in different thread at the same time even if they are guarded with Object level lock.

    Thanks,
    Kamal

  13. In one of the interview, I have asked a question. Synchronized means, thread will get lock on object/instance. what happened in case of static synchorized?I said that thread will get lockon class.then interviewer asked where/how does class exists? I stuck over here.Can you plz explain, how a thread get lock on class?where does the class(template) exists

    • What I could make out, in this question the interviewer switched from Thread to JVM internals for holding class & object. May be to confuse you for a while or to check the continuity of your knowledge.

      If that’s the case, then we all know that for object instances the memory area is called “Heap”.

      But for classes, there is another area called “Non-Heap” space is present in Permgen space of JVM. This has a segment called “Method Area”. This segment specifically houses the Class information e.g., code copy of all the methods of the class, irrespective of whether they are static or non-static, along with a host of other details pertaining to the member variables and access details.

      For more details you can refer to – https://blog.jamesdbloom.com/JVMInternals.html

  14. Hi, Lokesh , I want to ask you that does it mean that if we synchronize a block of code or method , we are are assured that it will always and successfully execute ?

    • Method will execute anyway. Synchronization means method will be executed in a multi-threaded environment like it is running in single thread. It means multiple threads will not have effect of one another in their execution path.

  15. Hi Lokesh, could you please explain the reason behind: “According to the Java language specification you can not use java synchronized keyword with constructor it’s illegal and result in compilation error”

    • Usually it is considered bad style to “give out” your not-yet-constructed object, so a synchronized constructor is not necessary.
      JLS actually says: “There is no practical need for a constructor to be synchronized, because it would lock the object under construction, which is normally not made available to other threads until all constructors for the object have completed their work.”

      But sometimes construction process is long enough to violate this rule so you can use synchronized block inside constructor. This is allowed.

      public class Test {
      public Test() {
      final Test me = this;
      synchronized(this) {
      new Thread() {
      @Override
      public void run() {
      // ... Reference 'me,' the object being constructed
      synchronized(me) {
      // do something dangerous with 'me'.
      }
      }
      }.start();
      // do something dangerous with this
      }
      }
      }

  16. Hi Lokesh,

    At RUNTIME, is it possible that two threads can access same synchronized block, object ?

    It seems that it can not happen, then how “Static Synchronized” and “Synchronized” declaration for any block or method behaves differently at run time.

    Say I have a data bean class that gets current USD to INR rate. For this it has a method that calls RBI webService to get current rate. Now please provide your view on difference in following conditions:

    1) If I declare – static synchronized getCurrentRate()
    2) If I declare – synchronized getCurrentRate()

    Also putting “Static Synchronized” in declaration of any method or code block, will impact performance more as compare to “Synchronized”

    I just want to make clear that exactly what is the difference between Class level and Object level Synchronization, in terms of performance and data inconsistency.

    Thanks.

    • Please again read class level locking description in post:

      “if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads. This should always be done to make static data thread safe.”

      Taking your example: (Let’s say getCurrentRate() method is defined in CurrencyConverter.java and there are 10 instances of this class)

      1) If I declare – synchronized getCurrentRate() : In this case, 10 seperate threads will be able to access this method in all 10 different instances. In simple words, 1 thread per instance. By the time, any thread is executing this method in any of instances, 11th thread must wait.

      2) If I declare – static synchronized getCurrentRate() : In this case, if one thread got access to instance one, then all other nine instances will also be locked and rest nine threads will be in waiting state. Once thread one finishes it’s job and release the lock, one of nine threads again will get access and rest eight will be in wait state.

      I will not try to compare the performance of both blocks because they are entirely different functionalities.

      As far as data consistency is concerned, non-static synchronized blocks are used to thread-safe instance level data, while static synchronized blocks are used to safe static data.

      • Hi Lokesh,

        Thanks for responding.

        Your explanation For synchronized getCurrentRate() : Seems that in this case , local variables are safe but not global and Static variables. In this case Local variables will not be accessed and updated by more than one thread. But in this case more than one thread can change values for Static and global variables.

        Can you provide a real World example for making it more clear.

        • What you re-iterated is completely true. It is essentially the way synchronization block works.

          I really never used static synchronized block as far i can remember (apart from tutorials). I will really appreciate if you update this conversation with your past experience if you have any.

          • Hi Lokesh,

            I have been reading some of your post and it is really informative and easy to follow.

            I just wanted to clarify one thing in this post, you mentioned that “static synchronized blocks are used to safe guard static data”.

            But my understanding is that the static data are inherently thread-safe as they are initialized during class loading which is guaranteed to be thread-safe by the JVM.

            Also it is my believe that no need to make the local variable thread-safe as each thread will have its own call stack so no issue of race condition.

            Regards,
            Satheesh

          • Thanks for sharing your views. I appreciate this. Synchronization is there to prevent the data from being corrupt when it is simultaneously accessed by two (or more) threads. You are right that at initialization time, data will be safe most of the time (not all the time if object creation process is long enough, in this case JVM may return the reference of not fully-prepared object). Still static data needs synchronization in other phases of application. Reason is that most JVM operations are multi-step (non-atomic) and there is high chances of data manipulation by two threads such that resulting data override each other’s changes.

    • Just want to clear few things, synchronization means synchronizing state changes of Object and that we can achieve it via synchronizing block in any java class. Now suppose there are 100 threads which trying to work with same object say obj1, which has some synchronized block, and all 100 threads trying to enter in that block.That point of time only one thread gets lock & will execute synchronized block.

      Now suppose all 100 threads trying to enter in synchronized block of java class with different- different Object instances say obj1, obj2……. obj100, Then all 100 threads can get entered in block because lock is on current obj.

      Suppose you have static synchronized block, locking get applied for javaclass.class object which is created during class loading.

Comments are closed.

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.