Showing posts with label synchronization. Show all posts
Showing posts with label synchronization. Show all posts

Synchronization in Java

In multi-threading resources will be shared by each thread and they can change or modify the values accordingly. Suppose lets see simple example where 2 people are having joint account in a bank and both are withdrawing cash. 1st person from ATM and 2nd person from bank exactly on same time. In that case only 1 operation can permitted between different users(Multiple Threads) to withdraw cash.  

Synchronization can control the access of multiple threads on shared resources. Without synchronization, it is possible for one thread to modify or to change the shared object while another thread accessing the same object value. This often leads to error and application gets failed. So we can use Synchronization to handle these situations like accessing shared memory or objects. 

Synchronization can be implemented in 2 ways like applying Synchronization to complete method or making a single block to Synchronization. Very important that Synchronization will work only same objects, most of the developers will be misunderstanding with Synchronization on multiple Objects of same class. 

Best example which we have already implemented and tested in Singleton Pattern with Synchronization block. Also below we will see simple example for Synchronization block on Synchronization method.


Main class for both Synchronized method and block testing. 


public class SynchronizationMethod {
 public static void main(String[] args) {
  MyTestThreadClass obj = new MyTestThreadClass();
  for(int i=0;i<10;i++){
   // Same MyTestThreadClass class object passing
   Thread t = new Thread(obj);
   t.start();
  }
 }
}

Synchronized method:


public class MyTestThreadClass implements Runnable{
 
 int i = 0; 
 
 public void run() {
  try{
   incrementValue();
   System.out.println(Thread.currentThread().getName() + ": "+i);
  }catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 private synchronized void incrementValue(){
  try{
   // Not allowing 'i' value to cross 6
   if(i <= 5){    
    // Making thread to sleep for few milliseconds
    Thread.sleep(new Random().nextInt(500));
    i++;
   }
  }catch (Exception e) {
   e.printStackTrace();
  }  
 }
}

OUTPUT:

Thread-0: 1
Thread-8: 2
Thread-9: 3
Thread-7: 4
Thread-5: 5
Thread-1: 6
Thread-6: 6
Thread-4: 6
Thread-2: 6
Thread-3: 6

We have used synchronized method in the above example and we can see the ouput that 'i' value didn't cross value 6. If we remove synchronized keyword in the method and if we test same code then we will get wrong output as like below 'i' value may get more than 6 even we place if condition.  


Thread-3: 1
Thread-6: 2
Thread-0: 3
Thread-8: 4
Thread-7: 5
Thread-5: 6
Thread-4: 7
Thread-2: 8
Thread-9: 9
Thread-1: 10

Synchronized block:

Synchronized method is nothing but applying Synchronized keyword to a block of keywork as like below example. 


public class MyTestThreadClass implements Runnable{
 
 int i = 0; 
 
 public void run() {
  try{
   incrementValue();
   System.out.println(Thread.currentThread().getName() + ": "+i);
  }catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 private void incrementValue(){
  try{
   synchronized (MyTestThreadClass.class) {
    if(i <= 5){    
     // Making thread to sleep for few milliseconds
     Thread.sleep(new Random().nextInt(500));
     i++;
    }
   }   
  }catch (Exception e) {
   e.printStackTrace();
  }  
 }
}

OUTPUT:

Thread-0: 1
Thread-7: 2
Thread-9: 3
Thread-8: 4
Thread-6: 5
Thread-4: 6
Thread-2: 6
Thread-1: 6
Thread-3: 6
Thread-5: 6