Showing posts with label synchronized method. Show all posts
Showing posts with label synchronized method. Show all posts

Sunday, 2 March 2014

static Synchronized methods

synchronized methods acquires a lock on object where as static synchronized methods acquire a lock on class. Only one object of particular class can enter into the static synchronized method at a time. One class has one class lock with it.

Syntax
   static synchronized returnType methodName(parameters){

   }

Example: without synchronization for static method    
class ClassLockEx implements Runnable{
 static void printMethod(){
  for(int i=0; i < 5; i++){
   try{
    Thread.currentThread().sleep(1000);
   }
   catch(Exception e){
    System.out.println(e);
   }
   System.out.println(Thread.currentThread().getName() + " " + i);
  }
 }

 public void run(){
  printMethod();
 }

 public static void main(String args[])throws Exception{
  ClassLockEx obj1 = new ClassLockEx();
  ClassLockEx obj2 = new ClassLockEx();
  Thread t1 = new Thread(obj1);
  Thread t2 = new Thread(obj2);
  t1.start();
  t2.start();
 }
}
    
Sample Output    
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-0 3
Thread-1 3
Thread-0 4
Thread-1 4

As you see run method calling the“ printMethod”, which is static, so both the objects obj1, obj2 has access to the static method. So both are running parallelly. By using static synchronized method, Only one object can run the method at a time.

Use of static synchronized method
class ClassLockEx implements Runnable{
 static synchronized void printMethod(){
  for(int i=0; i < 5; i++){
   try{
    Thread.currentThread().sleep(1000);
   }
   catch(Exception e){
    System.out.println(e);
   }
   System.out.println(Thread.currentThread().getName() + " " + i);
  }
 }

 public void run(){
  printMethod();
 }

 public static void main(String args[])throws Exception{
  ClassLockEx obj1 = new ClassLockEx();
  ClassLockEx obj2 = new ClassLockEx();
  Thread t1 = new Thread(obj1);
  Thread t2 = new Thread(obj2);
  t1.start();
  t2.start();
 }
} 

Output    

Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
   
With the help of static synchronization, until one object finishes it's execution with the static synchronized method, other objects must wait to run the same or other static synchronization methods of the same class.


Synchronized block                                                 static synchronized blocks                                                 Home

Synchronized block

There are some situation where you don't want to synchronize entire method, you want synchronization for particular lines of code, then synchronization block is there to help you
   Synatx
   synchronized ( obj ) {
      // block of code
   }

where obj is a reference to the object whose object-level lock must be acquired before entering the block of code.

Some points to Remember
1. Synchronization is costly operation, i.e, it contains overhead of acquiring and releasing of locks and other thread has to wait until the lock hold is released.

Example consider the below program, which will simply iterate a loop 1000000000 times
   
class WithOutSynchronization implements Runnable{
 public void run(){
  sum();
 }

 public void sum(){
  for(int i=0; i < 1000000000; i++){
  }
 }

 public static void main(String args[]) throws Exception{
  WithOutSynchronization task1 = new WithOutSynchronization();
  Thread t1 = new Thread(task1);
  Thread t2 = new Thread(task1);

  long time1 = System.currentTimeMillis();
  t1.start();
  t2.start();
  t1.join();
  t2.join();
  long time2 = System.currentTimeMillis();

  System.out.println("Time taken is " + (time2-time1));
 }
}
   
Output
Time taken is 5

will modify the above program, by applying synchronization

class WithSynchronization implements Runnable{
 public void run(){
  sum();
 }

 public void sum(){
  for(int i=0; i < 1000000000; i++){
   synchronized(this){
   }
  }
 }

 public static void main(String args[]) throws Exception{
  WithSynchronization task1 = new WithSynchronization();
  Thread t1 = new Thread(task1);
  Thread t2 = new Thread(task1);

  long time1 = System.currentTimeMillis();
  t1.start();
  t2.start();
  t1.join();
  t2.join();
  long time2 = System.currentTimeMillis();

  System.out.println("Time taken is " + (time2-time1));
 }
}
   
Output
Time taken is 18014

just compare the two outputs, for the first program with out synchronization takes 5 milliseconds to execute, with synchronization takes 18014 milliseconds to execute.

2. Is there any other situations where I can use synchronized block than synchronized method ?
Yes, of course, will explain with the below program.

Lets us assume there is a bucket, we can insert the elements into the bucket. What we want is, want to insert the elements into the bucket by thread1 at a time, and display the elements. The problem here is other thread also wish to insert. In this race condition we have to use synchronized block.

class BucketDemo{
 int stack[];
 int top = -1, size=0;

 BucketDemo(int size){
  stack = new int[size];
  this.size = size;
 }

 synchronized boolean isSpaceAvailable(){
  return (top < (size-1) );
 }

 synchronized void push(int ele){
  if(isSpaceAvailable()){
   top = top + 1;
   stack[top] = ele;
  }
 }

 void display(){
  for(int i=0; i < size; i++){
   System.out.println(stack[i]);
  }
 }
}

class BucketDemoThread1 implements Runnable{
 BucketDemo obj;

 BucketDemoThread1(BucketDemo obj){
  this.obj = obj;
 }

 public void run(){
  for(int i=0; i < 10; i++){
   obj.push(i);
   try {
    Thread.currentThread().sleep(1000);
   }
   catch(InterruptedException e){
   }
  }
 }
}

class BucketDemoThread2 implements Runnable{
 BucketDemo obj;

 BucketDemoThread2(BucketDemo obj){
  this.obj = obj;
 }

 public void run(){
  for(int i=10; i < 20; i++){
   obj.push(i);
   try{
    Thread.currentThread().sleep(1000);
   }
   catch(InterruptedException e){
   }
  }
 }
}

class SynchronizeBlock {
 public static void main(String args[]) throws Exception{
  BucketDemo obj = new BucketDemo(10);

  BucketDemoThread1 b1 = new BucketDemoThread1(obj);
  BucketDemoThread2 b2 = new BucketDemoThread2(obj);

  Thread task1 = new Thread(b1);
  Thread task2 = new Thread(b2);

  task1.start();
  task2.start();
  task1.join();
  task2.join();

  obj.display();
 }
}
   
Output:
0
10
1
11
12
2
13
3
4
14

but what we are expecting is printing the numbers from 1 to 10 only.

Now apply the synchronized statement to the classes BucketDemoThread1, BucketDemoThread2.

class BucketDemoThread1 implements Runnable{
 BucketDemo obj;

 BucketDemoThread1(BucketDemo obj){
  this.obj = obj;
 }

 public void run(){
  synchronized(obj){
   for(int i=0; i < 10; i++){
    obj.push(i);
    try {
     Thread.currentThread().sleep(1000);
    }
    catch(InterruptedException e){
    }
   }
  }
 }
}

class BucketDemoThread2 implements Runnable{
 BucketDemo obj;

 BucketDemoThread2(BucketDemo obj){
  this.obj = obj;
 }

 public void run(){
  synchronized(obj){
   for(int i=10; i < 20; i++){
    obj.push(i);
    try{
     Thread.currentThread().sleep(1000);
    }
    catch(InterruptedException e){
    }
   }
  }
 }
}

Output
0
1
2
3
4
5
6
7
8
9

synchronized methods                                                 static synchronized methods                                                 Home

Saturday, 1 March 2014

Synchronized Methods

Java programming language provides two strategies for basic synchronization :

Those are
   1. synchronized methods
   2. synchronized statements Block.

How to make a method synchronized
To make a method synchronized, simply add the synchronized keyword to its declaration

Example
synchronized int add(int a, int b)

Some points to remember about synchronized methods
1. It is not possible for two invocations of synchronized methods on the same object to interleave, i.e, if one thread executing a synchronized method of object obj1, then no other thread is able to execute any synchronized method of object obj1.

Example
class SynchMethEx implements Runnable{
 public void run(){
  printA();
 }

 synchronized void printA(){
  for(int i=0; i < 5; i++){
   System.out.println(Thread.currentThread().getName() + " A");
   try{
    Thread.currentThread().sleep(10);
   }
   catch(InterruptedException e){
   }
  }
 }

 synchronized void printB(){
  for(int i=0; i < 5; i++){
   System.out.println(Thread.currentThread().getName() + " B");
   try{
    Thread.currentThread().sleep(10);
   }
   catch(InterruptedException e){
   }
  }
 }

 public static void main(String args[]){
  SynchMethEx task1 = new SynchMethEx();
  Thread t1 = new Thread(task1);
  t1.setName("thread1");
  t1.start();
  task1.printB();
 }
}

Sample Output    
main B
main B
main B
main B
main B
thread1 A
thread1 A
thread1 A
thread1 A
thread1 A

Explanation
We have two synchronized methods printA and printB. Bothe have a printing statement inside. When one thread, let us assume main thread calls the printB method “task1.printB()” then thread t1 will wait until main thread finishes its execution with printB().

2. Okey, fine I understood that, if one thread executing a synchronized method of an object “task1” no other thread able to execute any synchronized method of object “task1”. Then what about non synchronized methods.
Non synchronized methods don't have any restriction on execution. I am removing the synchronization for the method printB in the above program, like below. Now compare the output.

class SynchMethEx implements Runnable{
 public void run(){
  printA();
 }

 synchronized void printA(){
  for(int i=0; i < 5; i++){
   System.out.println(Thread.currentThread().getName() + " A");
   try{
    Thread.currentThread().sleep(10);
   }
   catch(InterruptedException e){
   }
  }
 }

 void printB(){
  for(int i=0; i < 5; i++){
   System.out.println(Thread.currentThread().getName() + " B");
   try{
    Thread.currentThread().sleep(10);
   }
   catch(InterruptedException e){
   }
  }
 }

 public static void main(String args[]){
  SynchMethEx task1 = new SynchMethEx();
  Thread t1 = new Thread(task1);
  t1.setName("thread1");
  t1.start();
  task1.printB();
 }
}
    
Output

main B
thread1 A
main B
thread1 A
main B
thread1 A
main B
thread1 A
main B
thread1 A

3. when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads

4. Constructors can't be synchronized

5. No need to apply synchronization on final fields. Since once the final variable initialized for an object, its value never change.


6. When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.

Synchronization                                                 Synchronized block                                                 Home

synchronization

Synchronization is a process of orderly sharing of system resources

Will explore the need of synchronization and how to use it in java with an example.

Problem Description:
I have 2 threads want to print data from 0 to 4 in orderly. Like (0 1 2 3 4 0 1 2 3 4)

Solution without synchronization
class PrintWithOutSynch implements Runnable{
 public void run(){
  print1to10();
 }

 void print1to10(){
  for(int i=0; i < 10; i++){
   System.out.println(i);
   try{
    Thread.currentThread().sleep(1000);
   }
   catch(InterruptedException e){
   }
  }
 }

 public static void main(String args[]){
  PrintWithOutSynch task1 = new PrintWithOutSynch();
  Thread t1 = new Thread(task1);
  Thread t2 = new Thread(task1);
  t1.start();
  t2.start();
 }
}
    
Output
0 0 1 1 2 2 3 3 4 4

But we are expecting output like 0 1 2 3 4 0 1 2 3 4.

So what is wrong with this approach
Since threads are independent, both threads works parallel. If thread1 enters into sleep, thread2 has a chance to run, if thread2 enters into sleep, thread1 has a chance to run.

How to solve the problem
Make the print method as synchronized, if a method declared as synchronized, then at a time only one thread can enters into the synchronized method of a particular object(here for task1 object). Remaining threads wait until the thread which enters into the synchronized method finishes its execution or releases the lock voluntarily.

Solution with Synchronization
class PrintWithOutSynch implements Runnable{
 public void run(){
  print1to10();
 }

 synchronized void print1to10(){
  for(int i=0; i < 5; i++){
   System.out.print(i +" ");
   try{
    Thread.currentThread().sleep(1000);
   }
   catch(InterruptedException e){
   }
  }
 }

 public static void main(String args[]){
  PrintWithOutSynch task1 = new PrintWithOutSynch();
  Thread t1 = new Thread(task1);
  Thread t2 = new Thread(task1);
  t1.start();
  t2.start();
 }
}
   
Output

0 1 2 3 4 0 1 2 3 4


volatile keyword                                                 Synchronized methods                                                 Home