Synchronization in Java – 2023

0
784


Introduction

Synchronization in java is the aptitude to regulate the entry of a number of threads to any shared useful resource. In the Multithreading idea, a number of threads attempt to entry the shared assets at a time to provide inconsistent outcomes. The synchronization is critical for dependable communication between threads.

Why we use Synchronization

  • Synchronization helps in stopping thread interference.
  • Synchronization helps to stop concurrency issues.

Types of Synchronization

Synchronization is classed into two sorts

  • Process Synchronization
  • Thread Synchronization

Process Synchronization:

  • The course of is nothing however a program below execution. It runs independently remoted from one other course of. The assets like reminiscence and CPU time, and many others. are allotted to the method by the operation System.

Thread Synchronization:

Thread synchronization is 2 sorts, they’re:

1.Mutual Exclusive:

A Mutex or Mutual Exclusive helps just one thread to entry the shared assets. It gained’t enable the accessing of shared assets at a time. It might be achieved within the following methods.

  • Synchronized Method
  • Synchronized block
  • Static Synchronization

2. Cooperation (Inter Thread Communication in java)

Also test Java Tutorial for Beginners | An Overview of Java

Lock Concept in Java

  • Synchronization Mechanism developed through the use of the synchronized key phrase in java language. It is constructed on high of the locking mechanism, this locking mechanism is taken care of by Java Virtual Machine (JVM). The synchronized key phrase is simply relevant for strategies and blocks, it could possibly’t apply to courses and variables. Synchronized key phrase in java creates a block of code is called a vital part. To enter into the vital part thread must get hold of the corresponding object’s lock.

The drawback with out Synchronization:

Below instance reveals the Powers of the numbers like n1, n2, n3, n4, n5 

class Power{  
void printPower(int n){//technique not synchronized
   int temp = 1;
   for(int i=1;i<=5;i++){ 
     System.out.println(Thread.presentThread().getName() + ":- " +n + "^"+ i + " worth: " + n*temp);
     temp = n*temp;
     attempt{  
      Thread.sleep(500);  
     }catch(Exception e){System.out.println(e);}  
   }  
 }  
}  
class Thread1 extends Thread{  
Power p;  
Thread1(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(5);  
}    
}  
class Thread2 extends Thread{  
Power p;  
Thread2(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(8);  
}  
}  
  
public class Synchronization_Example1{  
public static void primary(String args[]){  
Power obj = new Power();//just one object  
Thread1 p1=new Thread1(obj);  
Thread2 p2=new Thread2(obj);  
p1.begin();  
p2.begin();
}  
}

Output:

Thread-1:- 8^1 worth: 8

Thread-0:- 5^1 worth: 5

Thread-1:- 8^2 worth: 64

Thread-0:- 5^2 worth: 25

Thread-1:- 8^3 worth: 512

Thread-0:- 5^3 worth: 125

Thread-1:- 8^4 worth: 4096

Thread-0:- 5^4 worth: 625

Thread-1:- 8^5 worth: 32768

Thread-0:- 5^5 worth: 3125

Here we didn’t use the synchronized key phrase so each the threads are executing at a time so within the output, thread-0 is interfering with thread-1, and therefore, we’re getting inconsistent outcomes.

Java Synchronized Method

If we use the Synchronized key phrases in any technique then that technique is Synchronized Method. 

  • It is used to lock an object for any shared assets. 
  • The object will get the lock when the synchronized technique is known as. 
  • The lock gained’t be launched till the thread completes its perform.

Syntax:

Acess_modifiers synchronized return_type method_name (Method_Parameters) {

// Code of the Method.

}

Java Synchronized Method Example:

class Power{  
synchronized void printPower(int n){//technique synchronized
   int temp = 1;
   for(int i=1;i<=5;i++){ 
        System.out.println(Thread.presentThread().getName() + ":- " +n + "^"+ i + " worth: " + n*temp);
     temp = n*temp;
     attempt{  
      Thread.sleep(500);  
     }catch(Exception e){System.out.println(e);}  
   }  
 }  
}  
class Thread1 extends Thread{  
Power p;  
Thread1(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(5);  
}  
}  
class Thread2 extends Thread{  
Power p;  
Thread2(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(8);  
}  
}  
public class Synchronization_Example2{  
public static void primary(String args[]){  
Power obj = new Power();//just one object  
Thread1 p1=new Thread1(obj);  
Thread2 p2=new Thread2(obj);  
p1.begin();  
p2.begin();
}  
}

Output:

Thread-0:- 5^1 worth: 5

Thread-0:- 5^2 worth: 25

Thread-0:- 5^3 worth: 125

Thread-0:- 5^4 worth: 625

Thread-0:- 5^5 worth: 3125

Thread-1:- 8^1 worth: 8

Thread-1: – 8^2 worth: 64

Thread-1:- 8^3 worth: 512

Thread-1:- 8^4 worth: 4096

Thread-1:- 8^5 worth: 32768

Here we used synchronized key phrases. It helps to execute a single thread at a time. It will not be permitting one other thread to execute till the primary one is accomplished, after completion of the primary thread it allowed the second thread. Now we will see the output accurately the powers 5 and eight from n1 to n5. Thread-0 accomplished then solely thread-1 start.

Synchronized Block

  • Suppose you don’t wish to synchronize the complete technique, you wish to synchronize few traces of code within the technique, then a synchronized block helps to synchronize these few traces of code. It will take the article as a parameter. It will work the identical as Synchronized Method. In the case of synchronized technique lock accessed is on the strategy however within the case of synchronized block lock accessed is on the article.

Syntax:

synchronized (object) {
//code of the block.
}
Program to know the Synchronized Block:
class Power{  
void printPower(int n){ 
synchronized(this){ //synchronized block
   int temp = 1;
   for(int i=1;i<=5;i++){ 
        System.out.println(Thread.presentThread().getName() + ":- " +n + "^"+ i + " worth: " + n*temp);
     temp = n*temp;
     attempt{  
      Thread.sleep(500);  
     }catch(Exception e){System.out.println(e);}  
   }  
 }  
}  
}
  
class Thread1 extends Thread{  
Power p;  
Thread1(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(5);  
}  
  
}  
class Thread2 extends Thread{  
Power p;  
Thread2(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(8);  
}  
}  
  
public class Synchronization_Example3{  
public static void primary(String args[]){  
Power obj = new Power();//just one object  
Thread1 p1=new Thread1(obj);  
Thread2 p2=new Thread2(obj);  
p1.begin();  
p2.begin();

}  
}

Output:

Thread-0:- 5^1 worth: 5

Thread-0:- 5^2 worth: 25

Thread-0:- 5^3 worth: 125

Thread-0:- 5^4 worth: 625

Thread-0:- 5^5 worth: 3125

Thread-1:- 8^1 worth: 8

Thread-1:- 8^2 worth: 64

Thread-1:- 8^3 worth: 512

Thread-1:- 8^4 worth: 4096

Thread-1:- 8^5 worth: 32768

In this instance, we didn’t synchronize the complete technique however we synchronized few traces of code within the technique. We acquired the outcomes precisely because the synchronized technique.

Static Synchronization

  • In java, each object has a single lock (monitor) related to it. The thread which is getting into into synchronized technique or synchronized block will get that lock, all different threads that are remaining to make use of the shared assets have to attend for the completion of the primary thread and launch of the lock.
  • Suppose within the case of the place we’ve multiple object, on this case, two separate threads will purchase the locks and enter right into a synchronized block or synchronized technique with a separate lock for every object on the identical time. To keep away from this, we’ll use static synchronization.
  • In this, we’ll place synchronized key phrases earlier than the static technique. In static synchronization, lock entry is on the category not on object and Method.

Syntax:

synchronized static return_type method_name (Parameters) {
//code
}
Or 
synchronized static return_type method_name (Class_name.class) {
//code
}

Program with out Static Synchronization:
class Power{  
 synchronized void printPower(int n){ //static synchronized technique
   int temp = 1;
   for(int i=1;i<=5;i++){ 
     System.out.println(Thread.presentThread().getName() + ":- " +n + "^"+ i + " worth: " + n*temp);
     temp = n*temp;
     attempt{  
      Thread.sleep(400);  
     }catch(Exception e){}  
   }  
  
 }  
}    
class Thread1 extends Thread{  
Power p;  
Thread1(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(2);  
}  
  
}

class Thread2 extends Thread{  
Power p;  
Thread2(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(3);  
} 
}  

class Thread3 extends Thread{  
Power p;  
Thread3(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(5);  
}  
} 

class Thread4 extends Thread{ 
Power p;  
Thread4(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(8);  
}  
} 

public class Synchronization_Example4{  
public static void primary(String args[]){ 
Power ob1 = new Power(); //first object
Power ob2 = new Power(); //second object
Thread1 p1 = new Thread1(ob1);  
Thread2 p2 = new Thread2(ob1); 
Thread3 p3 = new Thread3(ob2);
Thread4 p4 = new Thread4(ob2);

p1.begin();  
p2.begin();
p3.begin();
p4.begin();
}  
}

Output:

Thread-2:- 5^1 worth: 5

Thread-0:- 2^1 worth: 2

Thread-2:- 5^2 worth: 25

Thread-0:- 2^2 worth: 4

Thread-2:- 5^3 worth: 125

Thread-0:- 2^3 worth: 8

Thread-2:- 5^4 worth: 625

Thread-0:- 2^4 worth: 16

Thread-2: – 5^5 worth: 3125

Thread-0: – 2^5 worth: 32

Thread-3:- 8^1 worth: 8

Thread-1:- 3^1 worth: 3

Thread-3:- 8^2 worth: 64

Thread-1:- 3^2 worth: 9

Thread-3:- 8^3 worth: 512

Thread-1:- 3^3 worth: 27

Thread-3:- 8^4 worth: 4096

Thread-1:- 3^4 worth: 81

Thread-3:- 8^5 worth: 32768

Thread-1:- 3^5 worth: 243

If you observe the above outcomes Thread-0, Thread-1 belongs to object-1 and Thread-2, Thread-3 are belonging to Object-2. So, there is no such thing as a interference between thread 0 and 1 due to the identical object (obj1). In the identical method, there is no such thing as a interference between Thread 2 and three as a result of they belong to the identical object (obj2). But in the event you observe there may be interference between Thread 0 and a pair of, identical as there may be interference between Thread 1 and three. To rectify this drawback we’ll use static synchronization.

Program with static synchronization:

class Power{  
 synchronized static void printPower(int n){ //static synchronized technique
   int temp = 1;
   for(int i=1;i<=5;i++){ 
     System.out.println(Thread.presentThread().getName() + ":- " +n + "^"+ i + " worth: " + n*temp);
     temp = n*temp;
     attempt{  
      Thread.sleep(400);  
     }catch(Exception e){}  
   }  
  
 }  
}    
class Thread1 extends Thread{  
Power p;  
Thread1(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(2);  
}  
  
}

class Thread2 extends Thread{  
Power p;  
Thread2(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(3);  
} 
}  

class Thread3 extends Thread{  
Power p;  
Thread3(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(5);  
}  
} 

class Thread4 extends Thread{ 
Power p;  
Thread4(Power p){  
this.p=p;  
}  
public void run(){  
p.printPower(8);  
}  
} 

public class Synchronization_Example4{  
public static void primary(String args[]){ 
Power ob1 = new Power(); //first object
Power ob2 = new Power(); //second object
Thread1 p1 = new Thread1(ob1);  
Thread2 p2 = new Thread2(ob1); 
Thread3 p3 = new Thread3(ob2);
Thread4 p4 = new Thread4(ob2);

p1.begin();  
p2.begin();
p3.begin();
p4.begin();
}  
}

Output:

Thread-0:- 2^1 worth: 2

Thread-0:- 2^2 worth: 4

Thread-0:- 2^3 worth: 8

Thread-0:- 2^4 worth: 16

Thread-0:- 2^5 worth: 32

Thread-1:- 3^1 worth: 3

Thread-1:- 3^2 worth: 9

Thread-1:- 3^3 worth: 27

Thread-1:- 3^4 worth: 81

Thread-1:- 3^5 worth: 243

Thread-2:- 5^1 worth: 5

Thread-2:- 5^2 worth: 25

Thread-2:- 5^3 worth: 125

Thread-2:- 5^4 worth: 625

Thread-2:- 5^5 worth: 3125

Thread-3:- 8^1 worth: 8

Thread-3:- 8^2 worth: 64

Thread-3:- 8^3 worth: 512

Thread-3:- 8^4 worth: 4096

Thread-3:- 8^5 worth: 32768

In this static synchronization, we will observe there is no such thing as a interference between Thread-0 and Thread-2 identical as there is no such thing as a interference between Thread-1 and three. The subsequent thread is executing after the earlier thread completion or releasing lock solely.

Inter – Thread Communication

Inter – Thread communication or cooperation is a communication of two or extra threads with one another. It might be achieved through the use of the next strategies.

  • wait()
  • notify()
  • notifyAll()

Why we’d like Inter – Thread Communication?

  • There is a state of affairs on the thread that retains on checking some circumstances repeatedly, as soon as that situation satisfies thread strikes with the suitable motion. This state of affairs is called polling. This is a wastage of CPU time, to scale back the wastage of CPU time resulting from polling, java makes use of Inter – Thread Communication Mechanism.
  • wait(), notify(), notifyAll() strategies have to be known as inside a synchronized technique or block in any other case program will compile however once you run it, it is going to throw unlawful monitor State Exception.

Example:

class Power{  
void printPower(int n){
   int temp = 1;
   for(int i=1;i<=5;i++){ 
     System.out.println(Thread.presentThread().getName() + ":- " +n + "^"+ i + " worth: " + n*temp);
     temp = n*temp;
     attempt{  
        this.wait();    //wait positioned outdoors of the synchronized block or technique
      Thread.sleep(500);  
     }catch(Exception e){System.out.println(e);}  
   }  
  
 }  
}  

 Output:

Thread-0:- 5^1 worth: 5

java.lang.IllegalMonitorStateException

Thread-0:- 5^2 worth: 25

java.lang.IllegalMonitorStateException

Thread-0:- 5^3 worth: 125

java.lang.IllegalMonitorStateException

Thread-0:- 5^4 worth: 625

java.lang.IllegalMonitorStateException

Thread-0:- 5^5 worth: 3125

java.lang.IllegalMonitorStateException

Thread-1:- 8^1 worth: 8

java.lang.IllegalMonitorStateException

Thread-1:- 8^2 worth: 64

java.lang.IllegalMonitorStateException

Thread-1:- 8^3 worth: 512

java.lang.IllegalMonitorStateException

Thread-1:- 8^4 worth: 4096

java.lang.IllegalMonitorStateException

Thread-1:- 8^5 worth: 32768

java.lang.IllegalMonitorStateException

  1. wait () Method
  • It causes the present thread to put itself into the ready stage till one other thread invokes the notify() technique or notifyAll() technique for this object.
  1. notify () Method
  • This technique wakes up a single thread known as wait () on the identical object. If there may be multiple thread that’s ready on this identical object, then any one in every of them arbitrarily chosen to be woke up. Here woke up thread won’t capable of proceed till the present thread launch lock. If any threads are attempting to get the lock on this object then the woke up thread may also compete with them within the ordinary method.

Syntax:

public closing void notify()

  1. notify All() Method
  • Rather than a single thread, it is going to get up all of the threads ready on this object monitor. The woke up thread won’t capable of proceed till the present thread releases the lock. Again, these woke up threads have to compete with all different threads which are attempting to get the lock on this object.

Syntax:

public closing void notifyAll()

The Drawback of Synchronization Mechanism 

Synchronization Mechanism reveals much less efficiency.
Let’s contemplate an instance, if there are 5 course of P1, P2, P3, P4, P5 which might be ready to get the shared assets to entry just one thread at a time so, all different processes are in ready situation, the final course of has to attend till all different processes to be full. So, we’ve to make use of the synchronization idea the place we’ll get inconsistent outcomes.

If you have an interest in studying extra about Java go to Great Learning Academy.

LEAVE A REPLY

Please enter your comment!
Please enter your name here