Object Level Lock vs Class Level Lock in Java

Object level lock vs class level lock in Java with runnable proof that the two locks are independent, syntax variants, pitfalls and virtual thread notes.

Two Wallet instances with their own object locks and one Wallet.class lock shared by static synchronized methods

An object level lock is the lock of one instance, which a synchronized instance method or a synchronized (this) block takes, while a class level lock is the lock of the Class object, which a static synchronized method or a synchronized (Wallet.class) block takes. Every instance has its own object level lock, and each class has one class level lock that all instances share.

We use an object level lock to protect the fields of one instance, such as the balance of one wallet, so that two wallets can be updated in parallel. We use a class level lock to protect static data, such as a counter shared by all wallets.

The following example puts both kinds of lock in one class.

class Wallet {
    private int balance;                               // per wallet, guarded by the object lock
    private static int walletCount;                    // shared, guarded by the class lock

    synchronized void deposit(int amount) {            // locks this wallet
        balance += amount;
    }

    static synchronized void register() {              // locks Wallet.class
        walletCount++;
    }
}

Notice that the two methods use different locks, so a thread in deposit() never blocks a thread in register(). We cover each lock with its syntax variants, prove that they are independent, and go through the rules and pitfalls, from null locks to virtual threads.

1. Object Level Lock in Java

Every Java object has a built-in lock, also called its monitor. A thread that enters a synchronized instance method takes the lock of the object the method is called on, and other threads that need the same lock wait until it is released. We use the object level lock to make instance-level data thread safe.

There are three ways to write an object level lock. All three let one thread at a time into the guarded code for a given wallet, and threads that work on different wallets do not wait for each other.

class MethodLockWallet {
    private int balance;

    synchronized void deposit(int amount) {            // 1. synchronized method, locks this
        balance += amount;
    }
}

class ThisBlockWallet {
    private int balance;

    void deposit(int amount) {
        synchronized (this) {                          // 2. block on this
            balance += amount;
        }
    }
}

class PrivateLockWallet {
    private final Object lock = new Object();
    private int balance;

    void deposit(int amount) {
        synchronized (lock) {                          // 3. private lock object
            balance += amount;
        }
    }

    int balance() {
        synchronized (lock) {
            return balance;
        }
    }
}

The first two variants lock the same object, so they are equivalent. The third one is the safest, because no code outside the class can take a private lock and hold it by accident, which can happen with this when another class writes synchronized (wallet). A block also lets us keep the locked part short.

Say a payments app processes deposits from many users at once. Two deposits to the same wallet must not overlap, or one of them is lost, but deposits to different wallets can run in parallel. The following example sends 1,000 deposits from each of two threads to one wallet.

PrivateLockWallet shared = new PrivateLockWallet();
Thread first = Thread.ofPlatform().start(() -> { for (int i = 0; i < 1_000; i++) shared.deposit(1); });
Thread second = Thread.ofPlatform().start(() -> { for (int i = 0; i < 1_000; i++) shared.deposit(1); });
first.join();
second.join();
int balance = shared.balance();                         // 2000

Both threads use the lock of the same wallet, so no deposit is lost. Without the synchronized block, the read-add-write steps of the two threads can interleave, and the balance can end below 2000 with no error message.

2. Class Level Lock in Java

A class level lock is the lock of the Class object, such as Wallet.class. The JVM keeps one Class object per loaded class, so there is one class level lock no matter how many instances exist. A static synchronized method takes it, as defined in JLS 8.4.3.6, and we use it to make static data thread safe.

class IdGenerator {
    private static long nextId = 1;

    static synchronized long next() {                  // 1. static synchronized method
        return nextId++;
    }

    static long nextWithBlock() {
        synchronized (IdGenerator.class) {             // 2. block on the Class object
            return nextId++;
        }
    }
}

class AuditLog {
    private static final Object LOCK = new Object();   // 3. private static lock object
    private static int entries;

    static void record() {
        synchronized (LOCK) {
            entries++;
        }
    }
}

The IdGenerator class shows that the first two variants share the same lock, so next() and nextWithBlock() never return the same id. The third variant, a private static final lock object, again hides the lock from other code.

For example, an app gives every new wallet a unique id, and wallets are created in many request threads at once. The following example takes 500 ids from each of two threads.

Set<Long> ids = ConcurrentHashMap.newKeySet();
Thread a = Thread.ofPlatform().start(() -> { for (int i = 0; i < 500; i++) ids.add(IdGenerator.next()); });
Thread b = Thread.ofPlatform().start(() -> { for (int i = 0; i < 500; i++) ids.add(IdGenerator.nextWithBlock()); });
a.join();
b.join();
int uniqueIds = ids.size();                             // 1000

3. The Two Locks Are Independent

A class level lock does not block object level locks, and an object level lock does not block the class level lock, because they are locks on different objects. A thread inside a static synchronized method blocks only other code that synchronizes on the Class object. Instance synchronized methods of any wallet keep running.

Two Wallet instances with their own object locks and one Wallet.class lock shared by static synchronized methods
Each instance has its own lock, and the Class object has one more lock that only static synchronized code uses

The method Thread.holdsLock() shows which lock the current thread holds. The following class checks it from inside both kinds of method.

class LockProbe {
    synchronized boolean instanceMethodLocks() {
        return Thread.holdsLock(this) && !Thread.holdsLock(LockProbe.class);
    }

    static synchronized boolean staticMethodLocks() {
        return Thread.holdsLock(LockProbe.class);
    }

    static synchronized void holdClassLock(CountDownLatch entered, CountDownLatch release)
            throws InterruptedException {
        entered.countDown();
        release.await();                               // keeps the class lock until released
    }
}
LockProbe probe = new LockProbe();
boolean objectOnly = probe.instanceMethodLocks();       // true, this and not the class
boolean classLock = LockProbe.staticMethodLocks();      // true

To prove that the locks do not block each other, an auditor thread takes the class lock and keeps it. While it waits, the main thread calls an instance synchronized method, and the call returns without waiting.

CountDownLatch entered = new CountDownLatch(1);
CountDownLatch release = new CountDownLatch(1);
Thread auditor = Thread.ofPlatform().start(() -> {
    try {
        LockProbe.holdClassLock(entered, release);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
});
entered.await();                                        // the auditor holds LockProbe.class
LockProbe other = new LockProbe();
boolean notBlocked = other.instanceMethodLocks();       // true, returns at once
boolean auditorWaiting = auditor.isAlive();             // true
release.countDown();
auditor.join();

The same independence causes a classic bug. When an instance synchronized method changes a static field, each thread locks its own wallet, so two threads with two wallets update the shared field at the same time.

class BrokenWallet {
    static int totalDeposits;

    synchronized boolean deposit(CountDownLatch bothInside) {   // locks this, not BrokenWallet.class
        totalDeposits++;
        bothInside.countDown();
        try {
            return bothInside.await(1, TimeUnit.SECONDS);       // true when the other thread is inside too
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }
}

The following example calls deposit() on two wallets from two threads. Each call waits inside the method until the other call has also entered, which can only happen when the two calls do not share a lock.

BrokenWallet w1 = new BrokenWallet();
BrokenWallet w2 = new BrokenWallet();
CountDownLatch bothInside = new CountDownLatch(2);
Thread t1 = Thread.ofPlatform().start(() -> w1.deposit(bothInside));
boolean overlapped = w2.deposit(bothInside);            // true, both threads inside at once
t1.join();

Both threads were inside deposit() at the same moment, so their totalDeposits++ steps can interleave and lose updates under load. With a static synchronized method, the second call would wait for the first, so the first call’s await would time out and return false.

The fix is to guard static data with a class level lock, for example a static synchronized method, or to use an AtomicInteger for a simple counter. The rule is that every access to a field must use the same lock, whichever lock that is.

4. Object Level Lock vs Class Level Lock in Java

The two locks differ in the object they use and therefore in how many threads they can stop at once.

Object level lockClass level lock
Lock objectThe instance (this or a private field)The Class object (Wallet.class) or a private static field
Taken bysynchronized instance method, synchronized (this)static synchronized method, synchronized (Wallet.class)
Number of locksOne per instanceOne per class
BlocksThreads that use the same instanceThreads that use the class lock, across all instances
ProtectsInstance fieldsStatic fields
ParallelismDifferent instances run in parallelOne thread at a time for the whole class

Because a class level lock serializes all callers, it becomes a bottleneck faster. We keep static synchronized sections small, or replace a shared static counter with an atomic class or a ConcurrentHashMap.

5. Rules and Pitfalls of synchronized Locks

The same rules apply to both lock types, and most of them are defined for the synchronized statement in the Java Language Specification.

  • The synchronized keyword works only on methods and blocks. It cannot be used on fields or classes.
  • The lock is released when the thread leaves the method or block, either normally or because of an exception or error.
  • The lock is reentrant. A thread that holds a lock can call another synchronized method that needs the same lock without blocking.
  • A constructor cannot be synchronized, which JLS 8.8.3 forbids, because other threads normally cannot see the object until the constructor finishes.
  • Locking on a null reference throws NullPointerException.
static void lockOn(Object lock) {
    synchronized (lock) {
        // guarded code
    }
}
lockOn(null);                                           // NullPointerException
// does not compile: modifier synchronized not allowed here
class Account {
    synchronized Account() {
    }
}

A few choices of lock object compile fine and still break the locking. We avoid each of them.

  • A non-final lock field can be reassigned, and threads that read the old and the new reference lock different objects. Lock fields are always final.
  • String literals and boxed values such as Integer.valueOf(1) or Boolean.TRUE are shared across the whole JVM, so unrelated code can lock the same object and cause delays or a deadlock. We use a private final Object instead.
  • The call synchronized (getClass()) locks the Class object of the runtime type, so a subclass instance takes a different lock than the parent class. We write the class literal, such as Wallet.class.

Long synchronized sections slow an app down, because waiting threads do nothing useful. We lock only the lines that read or change shared state. Before Java 24, a virtual thread that blocked inside synchronized also pinned its carrier thread. JEP 491 removed that limitation in Java 24, so on Java 25 synchronized works well with virtual threads. When we need timeouts or interruptible waits, we use the Lock API instead.

6. Object and Class Level Lock FAQs

Static and instance methods in one class, and the choice of lock object, raise the same questions in almost every team.

6.1. Can a static and a non-static synchronized method run at the same time?

Yes. The static method locks the Class object and the instance method locks the instance, so the two never wait for each other, as the auditor example in section 3 shows.

6.2. Can two threads call the same synchronized method on different objects?

Yes, for an instance method. Each call locks its own object, so the threads run in parallel. For a static synchronized method, both calls use the class lock and run one after another.

6.3. Should we synchronize on this or on a private lock object?

We prefer a private final lock object. With this, any code that has a reference to our object can lock it too and delay our methods. A synchronized method is fine for small classes that are not shared with other code.

6.4. Does a class level lock block all instances of the class?

No. It blocks only code that synchronizes on the Class object, such as other static synchronized methods. Instance synchronized methods and unsynchronized code keep running on every instance.

7. Conclusion

An object level lock belongs to one instance and protects that instance’s fields, so different instances can work in parallel. A class level lock belongs to the Class object and protects static data for all instances at once.

The two locks never block each other, which is why static fields changed in instance methods are not thread safe. We guard each field with one lock, prefer private final lock objects over this, literals and getClass(), and use the Java concurrency utilities when plain synchronized is not enough.

8. References

Happy Learning !!

Source Code on Github

Leave a Comment

  1. Hi we have problem with my friends
    I read your post and seen that “Synchronization is the process” and i agree than your definitions, but my friend thinks that Synchronization it is mechanism

    could you explain your definition of why synchronization is a process and not a mechanism

    Tnx

    • I never thought in this way. But let me try to elaborate my understanding. “Synchronization is the process” which can be achieved with different mechanisms. Read/write locking is one of them, Semaphore can be other and so can be Mutex. This way I find Synchronization a high-level goal which involves designing algorithms, choosing appropriate data structures and various other factors.

      And I do not intend to say that your friends understanding is wrong. This is how you look at the term.

  2. 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 ?

  3. 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

  4. 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).

  5. 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

  6. 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(&quot;ABC&quot;); //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.

  7. “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.

  8. 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. :)

  9. ===================================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();
    }
    }

  10. 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?

  11. 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 ?

  12. 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.

      • hii lokesh sir.. i have a general doubt as. can we lock object except synchronization concept..
        i mean am creating object like ,
        Test t=new Test();
        now i want to lock t object with out using sync concept..
        is it possible

      • What changes should i make so that the output when the method is non static is equal to the output using static method. I don’t want to use static keyword. I just want to know how can we achieve this for non static methods.

        And one more thing. Can you please explain what object should we keep in synchronized public void testsync(‘object’) between the brackets. How do we decide what to keep here. I saw on most websites that thy keep a variable of the class here, even if that variable is not used anywhere in the method. Thanks in advance

  13. 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

  14. 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

  15. 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.

  16. 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
      }
      }
      }

    • Ramana, Whenever a class gets loaded by JVM, JVM creates an object which is called class.
      Say for example MyTest.java, where MyTest is class. So when MyTest gets loaded ‘MyTest.class’ object gets created.
      if MyTest class having any static syncronized method then lock would be on MyTest.class object.

      For more detail please visit

  17. 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.

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.