Acquiring lock on class, 2 Ways to acquire lock on class in java


In previous post we learned how to acquire object’s lock. Now, we will learn how to acquire lock on class’s class object. It’s very important to understand difference between object lock and class lock as well.

Thread can acquire lock on class’s class object by-
  1. Entering synchronized block or
  2. by entering static synchronized methods.


1) First let’s acquire lock on class’s class object by entering synchronized block.

Let’s say there is one class MyClass. Now we can create synchronization block, and parameter passed with synchronization tells which class has to be synchronized. In below code, we have synchronized MyClass
      synchronized (MyClass.class) {
        //thread has acquired lock on MyClass’s class object.
      }

As soon as thread entered Synchronization block, thread acquired MyClass’s class object. Thread will leave lock when it exits synchronized block.

It’s important to know that multiple objects of class may exist but there is always one class’s class object lock available.


Now, let’s create a program >
class MyRunnable1 implements Runnable{
   @Override
   public void run(){
     synchronized (MyClass.class) {
     for(int i=0;i<5;i++){
             System.out.println(i+" "+Thread.currentThread().getName()+" is executing");
             try {
                  Thread.sleep(500);
             } catch (InterruptedException e) {e.printStackTrace(); }
     }
    
     }
   }
                
}

/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class MyClass {
   public static void main(String args[]) throws InterruptedException{
          MyRunnable1 object1=new MyRunnable1();
          MyRunnable1 object2=new MyRunnable1();
         
          Thread thread1=new Thread(object1,"Thread-1");
          Thread thread2=new Thread(object2,"Thread-2");
          thread1.start();       
          thread2.start();       
         
         
   }
}
/*OUTPUT
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
*/
If you note output, Thread-1 entered synchronized block and was holding lock on MyClass’s class object. So, Thread-2 waited for Thread-1 to release lock on MyClass’s class object so that it could enter synchronized block.




2) Now let’s acquire object lock by entering static synchronized method.


Our static synchronized method looks like >

     public static synchronized void method1() {
        //thread has acquired lock on MyRunnable’s class object.
      }

As soon as thread entered Synchronization method, thread acquired lock on class’s class object.
Thread will leave lock when it exits static synchronized method.

It’s important to know that multiple threads may exist on same or different objects of class but only one thread can enter static synchronized method at a time.


Now, let’s create a program >
class MyRunnable implements Runnable{
   @Override
   public void run(){
          method1();
         
   }
   public static synchronized void method1(){
      for(int i=0;i<5;i++){
         System.out.println(i+" "+Thread.currentThread().getName()+" is executing");
         try {
                Thread.sleep(500);
         } catch (InterruptedException e) {e.printStackTrace(); }
      }
   }
                
}
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class MyClass {
   public static void main(String args[]) throws InterruptedException{
          MyRunnable object1=new MyRunnable();
          MyRunnable object2=new MyRunnable();
         
          Thread thread1=new Thread(object1,"Thread-1");
          Thread thread2=new Thread(object2,"Thread-2");
          thread1.start();       
          thread2.start();       
         
         
   }
}
/*OUTPUT
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
*/
If you note output, Thread-1 entered static synchronized method and was holding lock on MyRunnable’s class object. So, Thread-2 waited for Thread-1 to release lock on MyRunnable’s class object so that it could enter static synchronized method.


But, it may also happen that Thread-2 might enter static synchronized method first and in that case output will be -

/*OUTPUT
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
*/
If you note output, Thread-2 entered static synchronized method and was holding lock on MyRunnable’s class object. So, Thread-1 waited for Thread-2 to release lock on MyRunnable’s class object so that it could enter static synchronized method.







RELATED LINKS>

Object and class lock >

Acquiring object lock - synchronization blocks and methods- multiple threads may exist on same object but only one thread of that object can enter synchronized block/method at a time.
Acquiring lock on class, 2 Ways to acquire lock on class

Difference between object Lock and class Lock




Guidelines to threadsafe code >

No comments:

Post a Comment