The synchronized block in Java allows for synchronization to be applied to a particular resource within a method.
Imagine a scenario where a method consists of 50 lines of code, but there is a need to synchronize only a specific portion, say 5 lines. In such situations, a synchronized block can be employed.
Placing all method code inside a synchronized block achieves the same synchronization effect as using a synchronized method.
Points to Remember
- Synchronized block is used to lock an object for any shared resource.
- Scope of synchronized block is smaller than the method.
- A Java synchronized block doesn't allow more than one JVM, to provide access control to a shared resource.
- The system performance may degrade because of the slower working of synchronized keyword.
- Java synchronized block is more efficient than Java synchronized method.
Syntax
synchronized (object reference expression) {
//code block
}
Example of Synchronized Block
Let's examine a basic illustration of a synchronized block.
Example
//Creating a class which containse synchronized block within method
class Table
{
void printTable(int n){
synchronized(this){//synchronized block
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}//end of the method
}
//Creating Thread Class to call method
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
//Creating Main class to start threads
public class Main{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
Synchronized Block Example Using Anonymous Class
Consider the following illustration demonstrating a synchronized block in which threads are generated utilizing an anonymous class.
Example
//Creating a class which containse synchronized block within method
class Table
{
void printTable(int n){
synchronized(this){//synchronized block
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}//end of the method
}
//Creating Main class to create and start threads
public class Main{
public static void main(String args[]){
final Table obj = new Table();//only one object
Thread t1=new Thread(){
public void run(){
obj.printTable(5);
}
};
Thread t2=new Thread(){
public void run(){
obj.printTable(100);
}
};
t1.start();
t2.start();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
Message Passing Example using Synchronized Block
Let's explore another instance of a synchronized block where a message is being passed to the sender thread.
Example
// A Sender class
class Sender
{
public void SenderMsg(String msg)
{
System.out.println("Sending a Message: " + msg);
try
{
Thread.sleep(800);
}
catch (Exception e)
{
System.out.println("Thread interrupted.");
}
System.out.println(msg+ "Sent");
}
}
// A Sender class for sending a message using Threads
class SenderThread extends Thread
{
private String msg;
Sender sd;
// Receiver method to receive a message object and a message to be sent
SenderThread(String m, Sender obj)
{
msg = m;
sd = obj;
}
public void run()
{
// Checks that only one thread sends a message at a time.
synchronized(sd)
{
// synchronizing the sender object
sd.SenderMsg(msg);
}
}
}
// Creating a main class
public class Main
{
public static void main(String args[])
{
Sender sender = new Sender();
SenderThread sender1 = new SenderThread("Hola " , sender);
SenderThread sender2 = new SenderThread("Welcome to C# Programming website ", sender);
sender1.start();
sender2.start();
// wait for threads to end
try
{
sender1.join();
sender2.join();
}
catch(Exception e)
{
System.out.println("Interrupted");
}
}
}
Output:
Sending a Message: Hola
Hola Sent
Sending a Message: Welcome to C# Programming website
Welcome to C# Programming website Sent