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 Lazy. Java Interpreter interprets program/script code line by line while it is executed, but java Compiler compiles the complete program before starting the Interpretation. In eager instantiation, the object creation occurs at compile-time, so it is not considered efficient enough when we have large programs or many object instantiations as those might not be used. Lazy Instantiation means instantiating an object only when it is needed. This is considered efficient as it saves space and processing power when we consider large programs or many object instantiations.
Threads are considered as small individual components of processing that can execute in a parallel fashion to enhance/fasten the computation time. With advanced multi-core computers, threading has found a wide range of applications in programming. In the context of java, a thread-safe code is one that doesn’t provide anomalous output irrespective of how many times it is executed. Thread-safe code is very much essential for avoiding programming defects/flaws like race conditions, deadlocks, etc.
Back to lazy Instantiation which is often interchangeably referred to as on-demand instantiation has 2 methods of implementing itself they are as follows:
- Using synchronized keywords on the entire method/function is good when the method size is small and not many threads are going to access it soon as it is computation processing heavy.
- The next and more efficient way is the synchronized block way in which you just wrap around that code which needs to be thread-safe and to ensure more surety we wrap it with double-checked locking. The following approach of the hospital case study will help better understand these concepts in practical applications
The following is the approach followed in the script to demonstrate Lazy instantiation in a thread-safe environment (both synchronized method and synchronized block i.e. double-checked locking is covered) with the help of hospital-Operation case study is as follows:
- Assume there is a hospital that has potentially 1 operation theater wherein the surgeries would be performed on patients.
- The catch here is we would like to create a Hospital class object only when it is needed (when there is a patient whose operation needs to be performed) else the Hospital object would not be created — this is referred to as lazy Instantiation
- In order to demonstrate a multi-threaded environment, we are having various threads (t1, t2, t3, and t4) which are illustrated as patients.
- So let say if a patient whose operation needs to be performed we make Hospital object then and call operation() method which takes in the patient name as an argument.
- Then if the operation theater is empty or not the appropriate message would be displayed as to get ready for operation or whose surgery is currently being performed respectively.
- To make things more realistic and explain the concept of double-checked locking we are demonstrating the two ways of Lazy Instantiations those are synchronized methods (getInstanceSynchronizedWay()) which as explained above is a little less efficient/more expensive than the synchronized block way that is getInstanceSynchronizedBlockWay()
- Also, there are a few Thread.sleep() commenting inside the code for the purpose of demonstrating the thread-safety/serial execution of threads and tracking output is a controlled manner which would be further explained in the explanation Section.
The following is the scenario in which there is a hospital with only one operation theatre. So if the operation theatre is empty then take the patient for operation else display the sorry operation is carried for another patient. There are multiple threads created in this script with the illustration of each thread as a patient.
Explanation: The following is the explanation of the above case study Hospital with one operation theater,
- Initially, 2 threads namely t1 and t2 (illustrated as patients) are created in the main() method (inside Hospital class) and then those threads are running simultaneously with the program.
- Then these threads call the Synchronized Method (getInstanceSynchronizedBlockWay()) way to create/use the Lazy Instantiation of HospitalOperation class to perform an operation on patients named 123 and 789 respectively.
- Initially say default patient’s operation/surgery was going through in the operation theater. So until endOperation() method is not called prior to operation() method, it going to be busy and display Sorry message accordingly to the patient named 789 (thread t2) but for patient name 123 (thread t1) as endOperation() method is called prior to the operation() method call, 123 would be accepted for the surgery in the operation displaying the appropriate message as soon in the output screenshots.
- Exactly same process as above is repeated for patients ABC and XYZ (threads t1 and t2) to demonstrate the concept of double-checked locking that is a synchronized block way of doing Lazy Instantiation of the object.
- One thing to notice is the object id of HospitalOperation class is printed for t1 and t2 which is the same as they are demonstrating the synchronized method approach and object id is same for t3 and t4 is same as well as they are demonstrating synchronized block method which makes clear that HospitalOperation class acts as a Singleton class for each strategy of lazy instantiation types.
- Also, when the Thread.sleep() methods are un-commented from the code then the output occurs almost like threads are processing serially and not in a parallel fashion which ensures the same business logic (comparing figure 1 and 2 of sample output screenshots) is found in the output which demonstrates that the script is thread-safe.
Thus the above article explains Lazy Instantiation (both synchronized block along with double-checked locking and synchronized method approaches are covered) of Java classes (Singleton classes) with the help of Hospital-Operation case study example.