The getAppleInstance
method will make sure if the object of the Singleton
class is null then only it will create a new one else will return the existing one.
In single threaded
environment getAppleInstance
will work fine, but in multithreaded
environment, there might be a chance that 2 different threads will call getAppleInstance
at the same time for which if (Objects.isNull(appleInstance))
will return true and getAppleInstance
will return 2 Singleton
objects as shown below.
package org.wesome.dsalgo.design.pattern.singleton;
import java.util.Objects;
public class Apple {
static Apple appleInstance;
public Apple() {
System.out.println("Apple default constructor");
}
public static Apple getAppleInstance() {
System.out.println("Apple getAppleInstance");
if (Objects.isNull(appleInstance)) {
appleInstance = new Apple();
}
return appleInstance;
}
}
package org.wesome.dsalgo.design.pattern.singleton;
class AppleThread extends Thread {
public void run() {
Apple apple = Apple.getAppleInstance();
System.out.println("Object created by " + Thread.currentThread().getName() + " is " + apple);
}
}
public class SingletonClass {
public static void main(String[] args) {
AppleThread AppleThread1 = new AppleThread();
AppleThread AppleThread2 = new AppleThread();
AppleThread1.start();
AppleThread2.start();
}
}
To avoid single threaded
creating multiple Singleton
objects in multithreaded
environment, the getAppleInstance
can be synchronized to make sure only 1 thread will execute at a time and only 1 Singleton
object will be created as shown below.
package org.wesome.dsalgo.design.pattern.singleton;
import java.util.Objects;
public class Apple {
static Apple appleInstance;
public Apple() {
System.out.println("Apple default constructor");
}
public static synchronized Apple getAppleInstance() {
System.out.println("Apple getAppleInstance");
if (Objects.isNull(appleInstance)) {
if (Objects.isNull(appleInstance)) {
appleInstance = new Apple();
}
}
return appleInstance;
}
}
package org.wesome.dsalgo.design.pattern.singleton;
class AppleThread extends Thread {
public void run() {
Apple apple = Apple.getAppleInstance();
System.out.println("Object created by " + Thread.currentThread().getName() + " is " + apple);
}
}
public class SingletonClass {
public static void main(String[] args) {
AppleThread AppleThread1 = new AppleThread();
AppleThread AppleThread2 = new AppleThread();
AppleThread1.start();
AppleThread2.start();
}
}
plugins {
id 'java'
id "io.freefair.lombok" version "6.4.1"
}
group = 'org.wesome'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}
test {
useJUnitPlatform()
}
Pros of Synchronized Method
Only 1 thread will be able to access the getInstance method.
Cons of Synchronized Method
Method Synchronization will bring the performance down.