synchronization


                                               Synchronization
synchronization  is used to prevent thread interference and consistency problems while working with multiple threads.  i.e.  at a time only one thread is allowed to access any shared resource.
synchronization is categorized into two types as depicted below:


          Let us see the problem of multi threading without using synchronization . Here we are creating a Table class which contain printTable () method to print tables, two thread classes say FirstThread, SecondThread and a Test class .

Test.java

package syncronizedmethod;

class Table
{
     public  void  printTable( int num)
     {
          for(int i=1;i<=10;i++)
          {
              System.out.println(num+"X"+i+"="+num*i +"     "+Thread.currentThread().getName());
              try
              {
                   Thread.sleep(500);//sleeps the thread for 500 milli seconds
              }
              catch (InterruptedException e)
              {
                   e.printStackTrace();
              }
          }
     }
}

class FirstThread extends Thread
{
     Table t;
     int num;
     public FirstThread(Table t,int num)
     {
          this.t=t;
          this.num=num;
     }
     public void run()
     {
          t.printTable(num);
     }
}

class SecondThread extends Thread
{
     Table t;
     int num;
     public SecondThread(Table t,int num)
     {
          this.t=t;
          this.num=num;
     }
     public void run()
     {
          t.printTable(num);
     }
}

public class Test
{
     public static void main(String[] args)
     {
          Table t=new Table();
          FirstThread ft=new FirstThread(t, 5);
          SecondThread st=new SecondThread(t, 6);

          ft.start();
          st.start();
     }
}
output:

5X1=5      Thread-0
6X1=6      Thread-1
6X2=12     Thread-1
5X2=10     Thread-0
5X3=15     Thread-0
6X3=18     Thread-1
5X4=20     Thread-0
6X4=24     Thread-1
6X5=30     Thread-1
5X5=25     Thread-0
5X6=30     Thread-0
6X6=36     Thread-1
6X7=42     Thread-1
5X7=35     Thread-0
6X8=48     Thread-1
5X8=40     Thread-0
6X9=54     Thread-1
5X9=45     Thread-0
5X10=50    Thread-0
6X10=60    Thread-1

as we can see in the above output Thread-0(FirstThread) and Thread-1(SecondThread) are interfering.

Synchronized method
          Now let us see the solution to the above problem by using synchronized method. Here we are using same classes used in the above example. But we are making the printTable() method as synchronized method by adding the keyword synchronized.

package syncronizedmethod;

class Table
{
     public synchronized void printTable( int num)
     {
          for(int i=1;i<=10;i++)
          {
              System.out.println(num+"X"+i+"="+num*i +"     "+Thread.currentThread().getName());
              try
              {
                   Thread.sleep(500);//sleeps the thread for 500 milli seconds
              }
              catch (InterruptedException e)
              {
                   e.printStackTrace();
              }
          }
     }
}

class FirstThread extends Thread
{
     Table t;
     int num;
     public FirstThread(Table t,int num)
     {
          this.t=t;
          this.num=num;
     }
     public void run()
     {
          t.printTable(num);
     }
}

class SecondThread extends Thread
{
     Table t;
     int num;
     public SecondThread(Table t,int num)
     {
          this.t=t;
          this.num=num;
     }
     public void run()
     {
          t.printTable(num);
     }
}

public class Test
{
     public static void main(String[] args)
     {
          Table t=new Table();
          FirstThread ft=new FirstThread(t, 5);
          SecondThread st=new SecondThread(t, 6);

          ft.start();
          st.start();
     }
}

output:
5X1=5      Thread-0
5X2=10     Thread-0
5X3=15     Thread-0
5X4=20     Thread-0
5X5=25     Thread-0
5X6=30     Thread-0
5X7=35     Thread-0
5X8=40     Thread-0
5X9=45     Thread-0
5X10=50    Thread-0

6X1=6      Thread-1
6X2=12     Thread-1
6X3=18     Thread-1
6X4=24     Thread-1
6X5=30     Thread-1
6X6=36     Thread-1
6X7=42     Thread-1
6X8=48     Thread-1
6X9=54     Thread-1
6X10=60    Thread-1

How it works?
synchronization works based on Locks. If  any thread wants to access synchronized resource it has to acquire the lock and release the lock when it is done. so that another thread can access it by acquiring the lock.
There are two types of locks: 1) Locks with object
                                      2)Locks with class
synchronized block
          synchronized block is same as synchronized method except that the scope of the synchronized block is small.
·        If you want apply synchronization for entire method then we go for synchronized method.
·        If you want apply synchronization for some part of the code then we go for synchronized block.
syntax:
synchronized(object reference){}
Test.java
package syncronizedmethod;

class Table
{
     public  void printTable( int num)
     {
          synchronized(this)
          {
              for(int i=1;i<=10;i++)
              {
                   System.out.println(num+"X"+i+"="+num*i +"     "+Thread.currentThread().getName());
                   try
                   {
                        Thread.sleep(500);//sleeps the thread for 500 milli seconds
                   }
                   catch (InterruptedException e)
                   {
                        e.printStackTrace();
                   }
              }
          }
     }
}

class FirstThread extends Thread
{
     Table t;
     int num;
     public FirstThread(Table t,int num)
     {
          this.t=t;
          this.num=num;
     }
     public void run()
     {
          t.printTable(num);
     }
}

class SecondThread extends Thread
{
     Table t;
     int num;
     public SecondThread(Table t,int num)
     {
          this.t=t;
          this.num=num;
     }
     public void run()
     {
          t.printTable(num);
     }
}

public class Test
{
     public static void main(String[] args)
     {
          Table t=new Table();
          FirstThread ft=new FirstThread(t, 5);
          SecondThread st=new SecondThread(t, 6);

          ft.start();
          st.start();
     }
}

Output:
5X1=5      Thread-0
5X2=10     Thread-0
5X3=15     Thread-0
5X4=20     Thread-0
5X5=25     Thread-0
5X6=30     Thread-0
5X7=35     Thread-0
5X8=40     Thread-0
5X9=45     Thread-0
5X10=50    Thread-0
6X1=6      Thread-1
6X2=12     Thread-1
6X3=18     Thread-1
6X4=24     Thread-1
6X5=30     Thread-1
6X6=36     Thread-1
6X7=42     Thread-1
6X8=48     Thread-1
6X9=54     Thread-1
6X10=60    Thread-1

static synchronization
As we know synchronization works based on Locks. If  any thread wants to access synchronized resource it has to acquire the lock and release the lock when it is done. so that another thread can access it by acquiring the lock.
There are two types of locks: 1) Locks with object
                                      2)Locks with class
Locks with object:
·        every object has a lock. only one lock per object.
Locks with class:
·        every class has a lock. only one lock per class(for static methods)