Thursday, February 9, 2017

Synchronization and Inter-Thread communication in Java

Synchronization in java is the capability to control the access of multiple threads to any shared resource.
Synchronization is mainly used to avoid Race-Condition and Thread Safety in Application. 

There are some Issues caused by Synchroniation are:
    DeadLock: If not properly handled. Check this: http://deepakmodi2006.blogspot.in/2017/02/multithreading-issues-and-solutions-in.html
    Application becomes slow.

Types of synchronization:
    1)    Process Synchronization  (done at OS level)
    2)    Thread Synchronization
            --Mutual Exclusive  
                --Synchronized method
                --Synchronized block
                --static synchronization
            
            --Inter Thread Communication
                --wait and notify
            
We are going to discuss "Thread Synchronization".
            
Mutually Exclusive: means keeps threads away from interfering with one another while sharing data.
Synchronization is built around an internal entity known as the lock or monitor. 
Every object has an lock associated with it. Hence a thread which needs consistent access to an object's fields has to acquire 
the object's lock before accessing them, and then release the lock when it's done with them.


1) Synchronized method is used to lock an object for any shared resource. When a thread invokes a synchronized method, it 
   automatically acquires the lock for that object and releases it when the thread completes its task.
----------------------------------
 package threads;
 class BookMyShowTicketHelper{
     static int MAX_TICKET=10;
        synchronized boolean bookTicket(int n){
            if(MAX_TICKET-n>=0) {    
                MAX_TICKET = MAX_TICKET-n;
                System.out.println("MAX_TICKET: "+MAX_TICKET+", Ticket booked: "+n);
                return true;
            }    
            return false;
        } 
        public static void main(String ar[]){
            final BookMyShowTicketHelper obj = new BookMyShowTicketHelper();
            Thread t1 = new Thread(){ public void run() { obj.bookTicket(3); } };  //Access Synchronized method using Anonymous class
            Thread t2 = new Thread(){ public void run() { obj.bookTicket(2); } };  //Access Synchronized method using Anonymous class
            t1.start();
            t2.start();
        }
    }
----------------------------------
2) Synchronized block is used to lock an object for any shared resource. Scope of synchronized block is smaller than the method.
    boolean bookTicket(int n){
        if(MAX_TICKET-n>=0) {    
            MAX_TICKET = MAX_TICKET-n;
            System.out.println("MAX_TICKET: "+MAX_TICKET+", Ticket booked: "+n);
            return true;
        }    
            return false;
    }

3) Static Synchronization: If you make any static method as synchronized, the lock will be on the class not on object.
   Suppose there are 2 objects (Obj1 and Obj2) of BookMyShowTicketHelper class. 
   Obj1 is accessed by Thread t1 and t2. 
   Obj2 is accessed by Thread t3 and t4.
   
   By using synchronized method or block, Interference between t1 and t2 OR t3 and t4 is stopped, but
   interference between t1 and t3 OR t2 and t4 still can happen. Because each Object has one lock, hence t1 and t3 OR
   t2 and t4 has got other locks. Static Synchronization is at class level and is the solution here.
   
   synchronized static boolean bookTicket(int n){  return true/false; }
   
   OR
   
   static boolean bookTicket(int n) {  
        synchronized (BookMyShowTicketHelper.class) {       // Synchronized block on class   
            //...  
        }  
   }  

Inter-Thread Communication: It is a mechanism where a running thread is pausing itself in its critical section and allows other thread 
to enter (or lock) in the same critical section to be executed. It is implemented by following methods of Object class:
    wait()
    notify()
    notifyAll()   

wait(): This causes current thread to release the lock and wait until either another thread invokes the notify() method or the notifyAll() 
        method for this object, or a specified amount of time has elapsed (wait(long timeout) is wait for specified amount of time). But 
        the current thread must own this object's monitor, then only it can release the lock hence wait() must be called from the 
        synchronized method only otherwise it will throw exception.    Syntax: public final void wait()throws InterruptedException.

notify(): Wakes up a single thread that is waiting on this object's monitor. If many threads are waiting to get lock of this object, any one 
        of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation or at OS level. 
        Syntax: public final void notify()        

notifyAll(): Wakes up all threads that are waiting on this object's monitor. Syntax: public final void notifyAll()

Note: wait(), notify() and notifyAll() methods are defined in Object class because they are related to lock and object has a lock.
Difference between: wait() and sleep() method 
    wait() will push thread from running to waiting state.
    sleep() will push thread from running to runnable state.
    wait() will release the lock, but sleep() will be holding.
    wait(long) has timeout for waiting, else this will throw Interrupted Exception.
    wait() must be awakened by notify() or notifyAll(), but sleep() will be completed after specified time.
    wait() is in Object Class and non-static.
    sleep() is in Thread Class and static.

----------------------
    synchronized void withdraw(int amount){    
        if(this.amount<amount){  
            System.out.println("Less balance; waiting for deposit...");  
            try{  wait();  } catch(Exception e){ }  
        }  
        this.amount = this.amount - amount;  
        System.out.println("withdraw completed...");  
    }  
  
    synchronized void deposit(int amount){          
        this.amount = this.amount + amount;  
        System.out.println("deposit completed... ");  
        notify();  
    }  

Complete wait() and notify()
http://deepakmodi2006.blogspot.in/2011/01/wait-and-notify-in-java-wait-and-notify.html
----------------------

NOTE: 
The Java interpreter has a thread "scheduler" that manages all the threads of a program and decides which ones are to be run.
OS maintains a table containing list of Processes and List of Threads belonging to each process. New Processes/Threads gets added to the list.

Some helps taken from here: http://www.javatpoint.com/synchronization-in-java 

No comments:

Post a Comment