Java Program to Demonstrate the Lazy Initialization Non-Thread-Safe
Last Updated :
21 Jun, 2021
In recent years object-oriented programming has formed the pillars/bases of Website and Application (Software) Development. Java and Python are popular Object-Oriented programming languages out of which the former one is offered and maintained by Oracle, while the latter one is open-source. Java along with robust and easy-to-setup frameworks like spring frameworks makes the integration and configuration part of software development very easy and optimized. One of the four core pillars of Java Object-Orientation is referred to as Encapsulation which means binding Instances Variables and Methods often interchangeably referred to as functions, into a Class. The process of using those instance variables and methods using a new keyword to make a class object is called instantiation in java. We have two ways of doing Object Instantiation in Java, which are Eager & Lazy and both have their practical applications in the real world.
Lazy Instantiation is also referred to as On-Demand Instantiation in which the object of the class is only instantiated when it is required (that is dynamical). This helps us save computational processing power as well as memory when we are talking about huge software programs. Thread is like a small simple computational function/process of a program that can be run simultaneously in a parallel fashion to improve the processing speed. As day by day, we are moving towards multi-core powerful processing systems with high GPU/Clock Speed multi-threading have discovered a wide range of applications in programming. A thread-safe environment/code is such a code that even if run more than once (many times) then also produces desired business logic output and does not show anomalous behavior. This article tries to help us understand how lazy instantiation works in the practical world in a non-thread-safe environment and what can go wrong if we don't have thread-safe code.
Approach:
With the help of a simple case study of Restaurant Table booking, we will try to understand how Lazy Instantiation works and what happens to a non-thread-safe code in a multi-threaded environment. The following is the approach of our case study Restaurant Table Booking,
- There is a Restaurant class in the program which has the main() method in it and acts as a restaurant whose table can be booked/reserved online.
- Table1 which is illustrated as Singleton class is one of the tables in this Restaurant which be booked online.
- Various threads are created in the program which is illustrated as customers who are trying to reserve/book table1 via Lazy Instantiation of Table1 class.
- There is a simple check to see if table1 is already reserved/booked for another customer if so then a sorry message to the current customer request is displayed along with whose the table1 is already booked for, else the tabke1 is booked for the current customer name.
- Then we are having the ability to run two threads at the same time we demonstrate how an anomalous behavior is caused because the code is not thread-safe illustrating that if two customers try to reserve/book table1 at the same time then both might get a success message of booking but unfortunately the table1 would be reserved/booked only for 1 of them.
- Lastly, we introduce Thread.sleep() to have a delay of starting the third thread (customer) who get the correct message of the table is already reserved/booked which indicates that Lazy Instantiation works perfectly fine, but the code is non-thread-safe in the multi-threaded environment.
Implementation: Restaurant Table Booking
The following case study of Restaurant-Table booking will help us understand Lazy-Instantiation non-thread-safe. In this case study, we have a Restaurant that has a table named Table1 which is available for online booking/reserving. Various Threads are made which are illustrated as customers who are trying to book or reserve a table1. In the practical world, if the table1 is not booked it should be booked for 1st customer request and should display accordingly. If it's already booked it should display that sorry it is already booked for other customers (specify its name). We will see how if two threads (customers) if try to book the table simultaneously at the same time then it causes a mistake.
Example
Java
// Java Program to Demonstrate the Lazy initialization
// non-thread-safe
// Importing input output classes
import java.io.*;
// Class 1
// Helper class behaving as a Singleton Class
class Table1 {
// Lazy Instantiation also referred as On-demand
// Instantiation
// Private static member variables
private static Table1 table1;
private static String customerNameBooked;
// Constructor of this class which is private
// To display customer name whom table1 is booked for
private Table1(String customerName)
{
// Print and display the customer name
System.out.println("Table1 is now Booked for "
+ customerName);
// Booking under the same person
customerNameBooked = customerName;
}
// Non thread-safe block of code to
// demonstrate thread safe with updation in its methods
// Method 1
// To get the status of table
public static Table1
getTable1Instance(String customerName)
{
// If table is nor book/reserve
if (table1 == null) {
// book under the derired customer name
table1 = new Table1(customerName);
}
// If table is already booked
else
// Calling th method
tableBooked(customerName);
return table1;
}
// Method 2 (auxiliary)
// To display whom table is booked for
private static void tableBooked(String customerName)
{
// Print the custom name and
// name of customer under which table i booked
System.out.println(
"Sorry " + customerName
+ " Table 1 is already Booked for "
+ customerNameBooked);
}
}
// Class 2
// Main class
public class Restaurant {
// Main driver method
public static void main(String args[])
{
// Now we will be creating various threads as
// customer who wish to book Table1 in Restaurant
// Creating first customer(Thread-0)
// using Runnable interface
Thread t1 = new Thread(new Runnable() {
// run() method for the thread
public void run()
{
// Getting the table status
Table1 customer1
= Table1.getTable1Instance("ABC");
}
});
// Similarly repeating same for other customers
// Again creating second customer(Thread-1)
// using Runnable interface
Thread t2 = new Thread(new Runnable() {
// run() method for this thread
public void run()
{
Table1 customer2
= Table1.getTable1Instance("XYZ");
}
});
// Creating third customer(Thread-2)
// using Runnable interface
Thread t3 = new Thread(new Runnable() {
// run() method for this thread
public void run()
{
Table1 customer3
= Table1.getTable1Instance("PQR");
}
});
// Now starting the threads
// using start() method
t1.start();
t2.start();
// Try block to check for exceptions if any
try {
// Intentionally having a Thread.sleep(1000) to
// demonstrate not Thread-safe environment
Thread.sleep(1000);
}
// Catch block to handle the exceptions
catch (InterruptedException e) {
}
// Now starting the last thread via same means
t3.start();
}
}
Output:
Figure 1: Lazy Instantiation demonstration in the non-thread-safe environment.Output explanation: The above script code execution is displayed for which we will be gathering all aspects to get to know how it is non-thread-safe.
- Initially, we have 3 threads namely t1, t2, and t3 which are illustrated as customers with names ABC, XYZ, and PQR respectively who are trying to reserve/book Table1 in the Restaurant class.
- t1 and t2 are started simultaneously in the thread to demonstrate the multi-threading environment. Both calls method getTable1Instance() to book the table, here Table1 class behaves like singleton class of Java whose instance should only be created once illustrating table1 can be occupied by only 1 customer at a time.
- But as the code is non-thread-safe the table is booked for both the customers (namely ABC and XYZ) as we can see the instance of table1 is created twice in spite of it being marked to have the property of lazy Instantiation of Singleton class.
- Then we introduce a delay in starting the execution of thread t3 (with customer name as PQR) by having Thread.sleep(), so we can see now that the message displayed to PQR is correct according to the business logic that once the table was booked it should only show the sorry message to current customer and display for which customer the table is booked. This demonstrates that Lazy Instantiation works fine in serial fashion execution of threads that is non-thread-safe code.
- If there are multi-threads working in parallel fashion then the code show anomalous behavior by booking the same instance of the table for two customers who are trying to book at the same time, but eventually ending up a booking for one only whose name is then displayed for thread t3 (PQR) which is seen in figure 1 below which is sample output screenshot.
Conclusion: Thus with the help of a simple case study of Restaurant Table booking the concept of Lazy Instantiation in a Non-Thread-Safe environment/code is explained above.
Similar Reads
Java Program to Demonstrate the Lazy Initialization Thread-Safe
Java is a popular object-oriented programming language used by developers and coders for website/app development. The creation of a class object using a new keyword is referred to as object instantiation. Java by default allows users to define two ways of object instantiation which are Eager and Laz
7 min read
Java Threading Programs - Basic to Advanced
Java threading is the concept of using multiple threads to execute different tasks in a Java program. A thread is a lightweight sub-process that runs within a process and shares the same memory space and resources. Threads can improve the performance and responsiveness of a program by allowing paral
3 min read
Java Program to Create a Thread
Thread can be referred to as a lightweight process. Thread uses fewer resources to create and exist in the process; thread shares process resources. The main thread of Java is the thread that is started when the program starts. The slave thread is created as a result of the main thread. This is the
4 min read
How to make ArrayList Thread-Safe in Java?
In Java, Thread is the smallest unit of execution within the program. It represents an independent path of execution that can run concurrently with other threads. When dealing with multi-threaded applications, where multiple threads are accessing and modifying data concurrently, it's crucial to ensu
3 min read
How to Get the Id of a Current Running Thread in Java?
The getId() method of Thread class returns the identifier of the invoked thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime. When a thread is terminated, this thread ID may be reused. Java allows c
4 min read
Java Multithreading - One Thread to Take Input, Another to Print on Console
Multithreading is a concept in which our program can do two or more tasks at the same time. Thread is the execution unit of any process. Every process has at least one thread which is called main thread. In this article, we will create a Java program that will do printing on the console until the us
4 min read
How to Solve java.lang.IllegalStateException in Java main Thread?
An unexpected, unwanted event that disturbed the normal flow of a program is called Exception. Most of the time exception is caused by our program and these are recoverable. Example: If our program requirement is to read data from the remote file locating in U.S.A. At runtime, if a remote file is no
5 min read
How to Use Locks in Multi-Threaded Java Program?
A lock may be a more flexible and complicated thread synchronization mechanism than the standard synchronized block. A lock may be a tool for controlling access to a shared resource by multiple threads. Commonly, a lock provides exclusive access to a shared resource: just one thread at a time can ac
6 min read
Java Program to Use Exceptions with Thread
Exceptions are the events that occur due to the programmer error or machine error which causes a disturbance in the normal flow of execution of the program. When a method encounters an abnormal condition that it can not handle, an exception is thrown as an exception statement. Exceptions are caught
5 min read
How to Monitor a Thread's Status in Java?
The Java language support thread synchronization through the use of monitors. A monitor is associated with a specific data item and functions as a lock on that data. When a thread holds the monitor for some data item, other threads are locked out and cannot inspect or modify the data. In order to mo
3 min read