Thread Synchronization Practices in Java : Free Java Tutorials

We must follow some practices and rules while performing thread synchronization in Java. Every Java object has synchronized as well as non-synchronized area. The non-synchronized portion of an object can be accessed by multiple threads simultaneously. Whereas, the synchronized area can be accessed by only one thread at a time.

Whenever we perform any update operation like add, remove, replace, where the state of the object is changing, these types of operations should be inside the synchronized area. On the other hand, wherever object state is not going to change, those operations should be inside the non-synchronized area.

Concept of Critical Section in Thread Synchronization

A critical section or a critical region is a group of instructions/statements or region of code that needs to be executed atomically, that is, only one thread at a time should access this region of code.

In parallel programming, if one thread tries to change the value of shared variables at the same time as another thread tries to read or update the value, the result becomes unpredictable and irregular.

We must handle critical section problem using the synchronized keyword in Java.

Let’s understand this with an example.

class MyThread extends Thread 
{	
	Birthday obj;
	String name;

	MyThread(Birthday obj, String name)
	{
		this.obj = obj;
		this.name = name;
	}
	
	public void run()
	{
		obj.wishBirthday(name);
	}
	
}

class Birthday 
{	
	public void wishBirthday(String name)
	{
		for(int i=1;i<=5;i++)
		{
			System.out.print("Happy Birthday, ");
			try
			{
				Thread.sleep(2000);
			}
			catch(InterruptedException exp)
			{
				System.out.println("Thread has been interrupted");
			}
			System.out.println(name);
		}
	}
}

// Main class
public class Demo
{
	public static void main(String args[])
	{
		Birthday obj = new Birthday();
		MyThread thread1 = new MyThread(obj, "Meet");
		MyThread thread2 = new MyThread(obj, "Preet");
		
		thread1.start();
		thread2.start();
	}
}

In the above code, since we are not declaring wishBirthday() method as synchronized, both the threads will be executed simultaneously. Hence, we will get irregular output. That is, the order of execution of threads cannot be predicted.

We can see in the output that birthday statements are printed in arbitrary and irregular order for Meet and Preet.

Output:

Happy Birthday, Happy Birthday, Meet
Happy Birthday, Preet
Happy Birthday, Preet
Happy Birthday, Meet
Happy Birthday, Meet
Happy Birthday, Preet
Happy Birthday, Meet
Happy Birthday, Preet
Happy Birthday, Meet
Preet

This practice is not safe when there is any update operation that is to be executed by threads. It is recommended to use synchronized keyword to execute critical sections safely.

Look at the below example where wishBirthday() method is made synchronized.

class MyThread extends Thread 
{	
	Birthday obj;
	String name;

	MyThread(Birthday obj, String name)
	{
		this.obj = obj;
		this.name = name;
	}
	
	public void run()
	{
		obj.wishBirthday(name);
	}
	
}

class Birthday 
{	
	public synchronized void wishBirthday(String name)
	{
		for(int i=1;i<=5;i++)
		{
			System.out.print("Happy Birthday, ");
			try
			{
				Thread.sleep(2000);
			}
			catch(InterruptedException exp)
			{
				System.out.println("Thread has been interrupted");
			}
			System.out.println(name);
		}
	}
}

// Main class
public class Demo
{
	public static void main(String args[])
	{
		Birthday obj = new Birthday();
		MyThread thread1 = new MyThread(obj, "Meet");
		MyThread thread2 = new MyThread(obj, "Preet");
		
		thread1.start();
		thread2.start();
	}
}

Here, we declared wishBirthday() method as a synchronized method. So, at a time, only one thread is allowed to execute wishBirthday() method on the given Birthday object. Hence, we will get regular output.

Output:

Happy Birthday, Preet
Happy Birthday, Preet
Happy Birthday, Preet
Happy Birthday, Preet
Happy Birthday, Preet
Happy Birthday, Meet
Happy Birthday, Meet
Happy Birthday, Meet
Happy Birthday, Meet
Happy Birthday, Meet

This practice makes execution of critical section completely safe.

This is all about Thread Synchronization Practices in Java. Hope you find this tutorial helpful.

Leave a Comment

Your email address will not be published. Required fields are marked *