Saturday, August 27, 2016

More about Synchronization

How Synchronization Works in Java?

Synchronization in Java is important concept since Java is multithreaded language where multiple Threads run in parallel to complete program execution. 


In multithreaded environment synchronization of Java Object or synchronization of Java class becomes extremely important. 


Synchronization in Java possible by using Java keyword “synchronized” and “volatile”. 


Concurrent access of shared objects in Java introduces two kinds of errors:

Thread interference error.

Memory consistency error.


In order to avoid these errors you need to properly synchronize your java object to allow mutual exclusive access of critical section to two threads.


Why do we need synchronization in Java?


If  your code is executing in multi threaded environment you need synchronization of Java objects which are shared among multiple threads to avoid any corruption of state or any kind of unexpected behaviour. Synchronization in java will only be needed if shared object is mutable. If your shared object is read only or immutable object you don’t need synchronization despite running multiple threads. Same is true with what thread are doing with object if all threads are only reading value then you don’t require synchronization in java.JVM guarantees that Java synchronization code will only be executed by one thread at a time.


Java synchronized keyword provides following functionality essential for concurrent programming:

  • Synchronized keyword in java provides locking which ensures mutual exclusive access of shared resource and prevent data race.
  • Synchronized keyword also prevents reordering of code statement by compiler which can cause subtle concurrent issue if we don’t use synchronized or volatile keyword.
  • Synchronized keyword involve locking and unlocking. Before entering into synchronized method or block thread need to acquire the lock at this point it read data from the main memory than cache and when it releases the lock it flushes write operation into main memory which eliminate memory inconsistency error.

      From Java5 synchronized keyword in java was only way to provide synchronized of shared object.Any code written in synchronized block in java will be mutual exclusive and can only be executed by one thread at a time.You can have static synchronized method and non static synchronized method and synchronized blocks in java but u we can not have synchronized variable in java.Using synchronized keyword with variable is illegal and will result in compilation error.Instead of synchronized variable we can have volatile variable which will instructs JVM threads to read value of volatile variable from main memory and don't cache it locally.Block synchronized in java is preferred over method synchronization in java because by using block synchronization you only need to lock the critical section of code instead of whole method.Since java synchronization comes with the cost of performance we need to synchronize only part of code which absolutely needs to be synchronized.


      Example of synchronized method in java : 


      Using synchronized keyword along with method is easy just apply synchronized keyword in front of method.What we need to take care is that static synchronized method locked on class object and non static synchronized method locks on current object (this).So it is possible that both static and non static java synchronized method running in parallel.This is common mistake.


      public class Counter{

         private static count = 0;


        public static synchronized  getCount(){

             return this.count;

        }


        public synchoronized setCount(int count){

            this.count = count;

        }

        

      }

     

      In this example of java synchronization code is not properly synchronized because getCount() and setCount() are not getting locked on same object and can run parallel which result in getting incorrect count.Here getCount() will lock in Counter.class object while setCount() will lock on current object.(this).To make this object properly synchronized in java you need to either make both static or non static or use java synchronized block instead of java synchronized method.


      Example of synchronized block in Java :


      Using synchronized keyword in java is also similar to using synchronized keyword in method.Only important thing to note here is that if object used to lock synchronized block of code.Singleton.class in below example is null then the java synchronized block will throw a NullPointerException.


      public class Singleton{

          private static volatile Singleton _instance;


          public static Singleton getInstance(){


               if(_instance == null){

                      synchronized(Singleton.class){

                           if(_instance == null)

                               _instance = new Singleton();

                          }


              }

               return _instance;

       

       } 


       Important points of synchronized keyword in java :


  •       Synchronized keyword in java is used to provide mutual exclusive access of a shared resource with multiple threads in java.Synchronization in java guarantees that no two threads can execute a synchronized method which requires same lock simultaneously or concurrently.
  •       You can use java synchronized keyword only on synchronized method or synchronized block.
  •       When ever a thread enters into java synchronized method or block it acquires a lock and when ever it leaves java synchronized method or block it release the lock.Lock is released even if thread leaves synchronized method after completion or due to any Error or Exception.
  •      Java Thread acquires an object level lock when it enter into an instance synchronized java method and acquires a class level lock when it enters into static synchronized java method.
  •      Java synchronized keyword is re-entrant in nature it means if a java synchronized method calls other synchronized method which require same lock then current thread which is holding lock can enter into that method without acquiring lock.
  •       Java synchronization will throw NullPointerException if object used in java synchronized block is null.eg synchronized(myInstance) will throw NullPointerException if myInstance is null.
  •       One of the major disadvantage of java synchronized keyword.is that is does not allow concurrent read which can you implement using java.util.concurrent.locks.ReentrantLock.
  •       One of the limitation of java synchronization keyword is that it can only be used to access control of shared object within the same JVM.If you have more than one JVM and need to synchronized access to a shared file system or database, the java synchronized keyword is not at all sufficient.You need to implement global lock.
  •       Java synchronized block is better than java synchronized method.
  •       Its possible that both static synchronized and non synchronized method can run simultaneously or concurrently because they lock on different object.
  •       From java5 after change in Java memory model reads and write operation are atomic for all variable declared using volatile keyword.(Including long and double).Atomic variable are efficient then accessing variable in synchronized java code.But requires lots of attention to avoid memory consistency.
  •       Java synchronization could result in deadlock or starvation.while it get access by multiple thread.
  •       You can not make constructor synchronized. Because other thread will not be able to see if the object has been created or not.
  •       You can not apply synchronized keyword with variable and can not use volatile keyword with method.
  •       java.util.concurrent.locks extends capability provided by synchronization keyword and we can write more sophisticated programs since they offer more capabilities eg Reentrancy and interruptible lock.
  •       Java synchronization also synchronize memory.
  •       Important method related to synchronization in java are wait(),notify(),and notifyAll() which is defined in Object class.
  •       Do not synchronized non final field on synchronized block in java.It will give warning.Please check this link

      Its not recommended to use String object as lock in java synchronized block.because String is immutable object and literal string and interned string get stored in String pool.so by any chance if any other part of the code or any third party library used same string as there lock then they both will be locked on same object despite being completely unrelated which could result in unexpected behavior and bad performance.instead of string object it is advice to use new Object() for synchronization in java. on synchronization block.

                     private static final String LOCK = "lock";   //not recommended

                          private static final Object OBJ_LOCK = new Object(); //better

                        

                          public void process() {

                          synchronized(LOCK) {

                         ........

                        }

                    }

     From java library Calender and SimpleDateFormat classes are not thread safe and requires external synchronization in javato be used in multithreaded environment.

No comments:

Post a Comment

Required details

--------------------------------------------------------------------------------------------------------------------------- C:\Program File...