Open In App

Java Program to Demonstrate the Lazy Initialization Non-Thread-Safe

Last Updated : 21 Jun, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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-threadsafe code in a multi-threaded environment. The following is the approach of our case study Restaurant Table Booking,

  1. 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.
  2. Table1 which is illustrated as Singleton class is one of the tables in this Restaurant which be booked online.
  3. 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.
  4. 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.
  5. 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.
  6. 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 NonThread-Safe environment/code is explained above.

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads