In one of the interview I got asked about to how to make sure single object is present of a Singleton class when used with multiple classloaders.I followed this SO Question but I couldn't understand how we should invoke the getClass()
. As there is no information about it in the answer and as well as in the link provided in the answer.
I am new to classloaders and things aren't that clear for me. I have tried the code and tried multiple combination but every time I am getting two instance instead of one.
package com.design_pattern;
import java.io.*;
import java.lang.reflect.Constructor;
public class SIngletonPattern {
public static void main(String[] args) throws Exception {
DatabaseConnection databaseConnection = DatabaseConnection.getDatabaseConnection();
ClassLoader classLoader = SIngletonPattern.class.getClassLoader();
System.out.println(classLoader);
//Class classs = classLoader.getClass().forName(DatabaseConnection.class.getName());
Class classs = DatabaseConnection.getClass(DatabaseConnection.class.getName());
System.out.println(classs.getName());
Constructor[] declaredConstructors = classs.getDeclaredConstructors();
DatabaseConnection db2 = null;
for (Constructor d:declaredConstructors) {
d.setAccessible(true);
db2 = (DatabaseConnection) d.newInstance();
}
if(db2 == null){
System.out.println("null");
}else{
System.out.println(databaseConnection == db2);
}
}
}
class DatabaseConnection implements Serializable {
private static volatile DatabaseConnection databaseConnection;
private DatabaseConnection() {
System.out.println("Instance created");
}
public static DatabaseConnection getDatabaseConnection() {
System.out.println("getInstance()");
if (databaseConnection == null) {
synchronized (DatabaseConnection.class) {
if (databaseConnection == null) {
databaseConnection = new DatabaseConnection();
}
}
}
return databaseConnection;
}
protected Object readResolve() {
return databaseConnection;
}
public static Class getClass(String classname)
throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null)
classLoader = DatabaseConnection.class.getClassLoader();
return (classLoader.loadClass(classname));
}
}