Comparison of object locks and class locks in Java (synchronized)

In Java, a synchronized block of code can only be executed by one thread at a time. In addition, java supports multi-threaded concurrent execution. This may cause two or more threads to access the same field or object at the same time.

Synchronization is the process of keeping all executing concurrent threads in sync. Synchronization avoids memory consistency errors due to inconsistent views of shared memory. When a method is declared as synchronzied ; the thread holds the monitor or lock object of the method object. If another thread is executing a synchronized method, your thread will be blocked until that thread releases the monitor.

Note that we can use synchronized keyword on methods or blocks defined in a class. In a class definition, the synchronized keyword cannot be used with variables or properties.

1. Object level lock in Java


Object-level locks are a mechanism when we want to synchronize non-static methods or non-static code blocks so that only one thread can execute a code block on a given class instance. This should always be done to ensure instance-level data thread safety.

Object-level locking can be done as follows:

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)


A class-level lock prevents multiple threads from entering a synchronized block in any available instance of the class at runtime. This means that if there are 100 instances of DemoClass at runtime, only one thread at a time will be able to execute demoMethod() in any instance, while all other instances will be locked by other threads.

Class-level locking should always be performed to ensure static data thread safety. We know that the static keyword associates the data of the method with the class level, so use a lock on a static field or method to make it on the 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 locks vs. class-level locks – important notes

  1. Synchronization in Java guarantees that no two threads can execute a synchronized method concurrently or concurrently, which requires the same lock.
  2. The Synchronized keyword can only be used with methods and code blocks. These methods or blocks can be static or non-static.
  3. When a thread enters a Java synchronized method or block, it acquires the lock; whenever the thread leaves the synchronized method or block, it releases the lock. The lock is released even if the thread leaves the synchronized method after completion or due to any error or exception.
  4. Java's synchronized keyword is essentially re-entrant, meaning that if a synchronized method calls another synchronized method that requires the same lock, the thread currently holding the lock can enter the method without acquiring the lock.
  5. Java synchronization will throw a NullPointerException if the object used in the synchronized block is null. For example, in the code sample above, "synchronized(lock)" will throw NullPointerException if lock is initialized to null.
  6. Synchronous methods in Java impose a performance cost on the application. Therefore, use synchronization when absolutely necessary. Also, consider using synchronized code blocks to synchronize only critical sections of your code.
  7. Static synchronized and non-static synchronized methods may run concurrently or concurrently because they lock different objects.
  8. According to the Java Language Specification, the synchronized keyword cannot be used in constructors. This is illegal and will cause a compilation error.
  9. Do not synchronize on non-final fields of synchronized blocks in Java. Because references to non-final fields may change at any time, and then different threads may synchronize on different objects, i.e. not synchronize at all.
  10. Do not use string literals as they may be referenced elsewhere in the application and may cause a deadlock. String objects created using the new keyword are safe to use. But as a best practice, create a new private scope object instance or lock the shared variable we want to protect itself. [Thanks to Anu for pointing this out in the comments.

References

Class Level Lock in Java - GeeksforGeeks

Guess you like

Origin blog.csdn.net/keeppractice/article/details/131828437