What is Synchronization, and why is it used?
Multiple threads trying to access the same resources in a multithreaded program may frequently result in unexpected and incorrect results. Therefore, it must be ensured through some form of synchronization that only one thread can access the resource at any given time.
- Java offers a method for setting up threads and synchronizing their operations with the aid of synchronized blocks.
- The synchronized keyword in Java is used to identify synchronized blocks. In Java, a synchronized block is one that is tied to an object.
- Only one thread can be running at a time inside synchronized blocks since they are all synchronized on the same object.
- Until the thread inside the synchronized block exits the block, all other threads trying to enter the block are blocked.
Syntax:
synchronized (object)
{
//statement to be synchronized
}
Synchronized Java Method:
- Any method is referred to as a synchronized method if you declare it to be so.
- Locking an object for any shared resource involves using a synchronized method.
- A thread automatically acquires the lock for an object when it calls a synchronized method, and it releases the lock once the thread has finished its work.
The problem without Synchronization:
The below example shows the Powers of the numbers like n1, n2, n3, n4or n5.
public class Power{
void printPower(int n){//method not synchronized
int temp = 1;
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName() + ":- " +n + "^"+ i + " value: " + n*temp);
temp = n*temp;
try
{
Thread.sleep(500);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
}
public class Thread1 extends Thread
{
Power p;
Thread1(Power p)
{
this.p=p;
}
public void run()
{
p.printPower(5);
}
}
public 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 main(String args[])
{
Power obj = new Power();//only one object
Thread1 p1=new Thread1(obj);
Thread2 p2=new Thread2(obj);
p1.start();
p2.start();
}
}
Output:
Thread-1:- 8^1 value: 8
Thread-0:- 5^1 value: 5
Thread-1:- 8^2 value: 64
Thread-0:- 5^2 value: 25
Thread-1:- 8^3 value: 512
Thread-0:- 5^3 value: 125
Thread-1:- 8^4 value: 4096
Thread-0:- 5^4 value: 625
Thread-1:- 8^5 value: 32768
Thread-0:- 5^5 value: 3125
Above Example using Synchronized Method :
public class Power{
synchronized void printPower(int n){//method synchronized
int temp = 1;
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName() + ":- " +n + "^"+ i + " value: " + n*temp);
temp = n*temp;
try
{
Thread.sleep(500);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
}
public class Thread1 extends Thread
{
Power p;
Thread1(Power p)
{
this.p=p;
}
public void run()
{
p.printPower(5);
}
}
public 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 main(String args[])
{
Power obj = new Power();//only one object
Thread1 p1=new Thread1(obj);
Thread2 p2=new Thread2(obj);
p1.start();
p2.start();
}
}
Output:
Thread-0:- 5^1 value: 5
Thread-0:- 5^2 value: 25
Thread-0:- 5^3 value: 125
Thread-0:- 5^4 value: 625
Thread-0:- 5^5 value: 3125
Thread-1:- 8^1 value: 8
Thread-1: – 8^2 value: 64
Thread-1:- 8^3 value: 512
Thread-1:- 8^4 value: 4096
Thread-1:- 8^5 value: 32768
Above Example using Synchronized Block :
public class Power
{
void printPower(int n)
{
synchronized(this)
{ //synchronized block
int temp = 1;
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName() + ":- " +n + "^"+ i + " value: " + n*temp);
temp = n*temp;
try
{
Thread.sleep(500);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
}
}
public class Thread1 extends Thread
{
Power p;
Thread1(Power p)
{
this.p=p;
}
public void run()
{
p.printPower(5);
}
}
public 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 main(String args[])
{
Power obj = new Power();//only one object
Thread1 p1=new Thread1(obj);
Thread2 p2=new Thread2(obj);
p1.start();
p2.start();
}
}
Output:
Thread-0:- 5^1 value: 5
Thread-0:- 5^2 value: 25
Thread-0:- 5^3 value: 125
Thread-0:- 5^4 value: 625
Thread-0:- 5^5 value: 3125
Thread-1:- 8^1 value: 8
Thread-1:- 8^2 value: 64
Thread-1:- 8^3 value: 512
Thread-1:- 8^4 value: 4096
Thread-1:- 8^5 value: 32768
Difference between synchronized method and block:
Basis | Synchronized Method | Synchronized Block |
Scope of lock | Synchronized method does not reduce the scope of the lock. | Synchronized block generally reduces the scope of the lock. |
Control over the lock | If a synchronized method is static, it always locks either on the object currently represented by this keyword or a class-level lock. | Synchronized blocks give you fine-grained control over a lock because any lock can be used to mutually exclude critical section code. |
NullPointerExcpetion | The synchronized method does not throw java.lang.NullPointerException. | Synchronized block can throw java.lang.NullPointerException if expression provided to block as parameter evaluates to null |
Lock Acquisition | When a thread enters a synchronized method, it acquires the lock. When the thread exits the method, it can do so normally or by throwing an exception. | in the case of the synchronized block, the thread acquires a lock when they enter the synchronized block and release it when they leave the synchronized block. |
Note: also read about the Daemon thread in Java
Follow Me
If you like my post, please follow me to read my latest post on programming and technology.
https://www.instagram.com/coderz.py/
https://www.facebook.com/coderz.py
Staying up to the mark is what defines me. Hi all! I’m Rabecca Fatima a keen learner, great enthusiast, ready to take new challenges as stepping stones towards flying colors.
Leave a Comment