AppDividend
Latest Code Tutorials

Java Synchronized Example | Synchronization in Java Tutorial

0

Java Synchronized Example | Synchronization in Java Tutorial is today’s topic. If multiple threads are accessing a resource, there needs to be some check or safeguard that the resource is being used by only one thread at a time to avoid disastrous consequences. The process by which this is achieved is called synchronization. Java provides language-level support for synchronization.

The way that the synchronization is used is by the use of what is called a monitor. A monitor can be owned by only one thread at a given time. When a thread “acquires” a monitor or “enters” a monitor, no other thread can enter the said monitor. The other thread is kept waiting for the monitor to be freed. A thread which already owns the monitor can reenter it if required. A monitor is an object which is thus used as a mutually exclusive lock.

Java Synchronized Example

Content Overview

Synchronization in Java is a capability to control the access of multiple threads to any shared resource.

Java Synchronization is the better option where we want to allow only one thread to access any shared resource.

The way that the synchronization is used is by the use of what is called a monitor. When a thread “acquires” a monitor or “enters” a monitor, no other thread can enter the said monitor. A monitor is an object which is thus used as a mutually exclusive lock.

Why use Synchronization

The synchronization is mainly used to

  1. To prevent thread interference.
  2. To prevent the consistency problem.

Types of Synchronization

There are two types of synchronization in Java.

  1. Process Synchronization
  2. Thread Synchronization

In this post, we will discuss only thread synchronization.

Thread Synchronization

There are two types of thread synchronization.

mutual exclusive and inter-thread communication.

  1. Mutual Exclusive
    1. Synchronized method.
    2. Synchronized block.
    3. Static synchronization.
  2. Cooperation (Inter-thread communication in java)

Mutual Exclusive helps keep threads from interfering with one another while sharing data. This can be done by three ways in java:

  1. Using the synchronized method
  2. Using a synchronized statement
  3. Static synchronization

Using synchronized Methods

In Java, all objects have their implicit monitors associated with them. To enter an object’s monitor, one has to call a method that has been modified with the synchronized keyword. The thread exits this monitor when the method returns. While a thread has called a synchronized method of an instance, all other threads wanting to enter any synchronized method of that instance must wait.

Now, to explain the importance of synchronization, let’s take up an example where three flights are requesting the control tower for permission to land in the same runway. Now, it’s the job of the control tower to ensure that it permits a flight to land only when the runway is clear. Otherwise, the consequences are bound to be disastrous.

See the following SynDemo.java example.

// SynDemo.java

class ControlTower{
	void permission(String message){
		System.out.print("[[" + message);
		try{
			Thread.sleep(2000);
		}catch(InterruptedException e){
			System.out.println("Interrupted");
		}
		System.out.println("]]");
	}
}

class Flight implements Runnable{
	String message;
	ControlTower target;
	Thread t;

	public Flight(ControlTower targ, String s){
		target=targ;
		message=s;
		t=new Thread(this);
		t.start();
	}

	public void run(){
		
		synchronized(target){
		target.permission(message);
		}
	}
}

class SynDemo{
	public static void main(String [] args){
		ControlTower target=new ControlTower();

		Flight flight1= new Flight(target, "Flight 1");
		Flight flight2= new Flight(target, "Flight 2");
		Flight flight3= new Flight(target, "Flight 3");

		try{
			flight1.t.join();
			flight2.t.join();
			flight3.t.join();
		}catch(InterruptedException e){
			System.out.println("Interrupted");
		}
	}
}

 

Java Synchronized Example

Here, individual threads are being created in the Flight class, which calls the void permission(String message) method of the ControlTower class to pass the said message.

Now, in the primary method, one instance of class ControlTower is created, and three instances of Flight are created, which are interacting with the same ControlTower instance target.

As you can see, Thread.sleep(2000) makes each thread sleep for 2 seconds, which means another thread is free to call the permission(String message) method even though one thread has not fully finished executing. In our example, this leads to a disastrous outcome – the flights land one after the another without the runway being cleared.

See the below output.

Synchronization in Java Tutorial

 

To fix this, only one change is required in the above program. The method permission needs to be synchronized, which means that no other thread can call it until and unless the thread which has entered is an exit.

// SynDemo.java

class ControlTower{
	synchronized void permission(String message){
		System.out.print("[[" + message);
		try{
			Thread.sleep(2000);
		}catch(InterruptedException e){
			System.out.println("Interrupted");
		}
		System.out.println("]]");
	}
}

class Flight implements Runnable{
	String message;
	ControlTower target;
	Thread t;

	public Flight(ControlTower targ, String s){
		target=targ;
		message=s;
		t=new Thread(this);
		t.start();
	}

	public void run(){
		target.permission(message);
	}
}

class SynDemo{
	public static void main(String [] args){
		ControlTower target=new ControlTower();

		Flight flight1= new Flight(target, "Flight 1");
		Flight flight2= new Flight(target, "Flight 2");
		Flight flight3= new Flight(target, "Flight 3");

		try{
			flight1.t.join();
			flight2.t.join();
			flight3.t.join();
		}
                catch(InterruptedException e){
			System.out.println("Interrupted");
		}
	}
}

See the following output.

Using synchronized methods

 

Using the synchronized statement

Now, one may not always have direct access to the method which requires the synchronization. It may be in another file or be provided by a third party. In such a case, synchronization is achieved by putting the statements required to be synchronized inside a synchronized block, as shown below. The same program has been modified to demonstrate this use.

See the following example.

class ControlTower{
	synchronized void permission(String message){
		System.out.print("[[" + message);
		try{
			Thread.sleep(2000);
		}catch(InterruptedException e){
			System.out.println("Interrupted");
		}
		System.out.println("]]");
	}
}

class Flight implements Runnable{
	String message;
	ControlTower target;
	Thread t;

	public Flight(ControlTower targ, String s){
		target=targ;
		message=s;
		t=new Thread(this);
		t.start();
	}

	public void run(){
		
		
		target.permission(message);
		
	}
}

class SynDemo{
	public static void main(String [] args){
		ControlTower target=new ControlTower();

		Flight flight1= new Flight(target, "Flight 1");
		Flight flight2= new Flight(target, "Flight 2");
		Flight flight3= new Flight(target, "Flight 3");

		try{
			flight1.t.join();
			flight2.t.join();
			flight3.t.join();
		}catch(InterruptedException e){
			System.out.println("Interrupted");
		}
	}
}

The output is following.

Using the synchronized statement

 

Finally, Java Synchronized Example | Synchronization in Java Tutorial is over.

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.