Oracle Interview Question
Software Engineer / DevelopersCountry: India
Interview Type: In-Person
Jdev is using double locked mechanism for thread safe singleton object creation. However, compiler is free to assign value to 'object' variable before 'object' is initialized.
For instance, thread1 can create an instance of SingletonObject class but before it initializes it can preempted. So another thread2 can still find 'object' == null and try to create another instance of SingletonObject class.
To avoid that easiest way is to use synchronized method instead of block
Or we can create public member of class which is initialized when first time class is used.
public class SingletonObject{
public final static object = new SingletonObject();
private SingletonObject(){
// To avoid misuse of constructor
}
}
synchronized method do work for sure. But again the question is what is the best way. Every time acquiring a lock for getting an object is leads to performance issue when heavily loaded.
Creating Object in advance works well. But then what if the object is never called. And probably this is not what interviewer was looking for.
This is a cleaner version of the earlier code.
volatile SingletonObject object;
getInstance()
{
if(object == null)
{
synchronized(obj)
{
//Only one thread can come here
//Make sure object is not created already. Object is volatile. Ensures that the JVM will see the correct copy of object.
if(object == null )
{
object = new SingletonObject();
}
//Note this is a DCL implementation. This prevents from creating the object twice by two different threads.
}
}
return object;
}
Although as mentioned by several others the best and easiest way to ensure singleton behaviour would be by instantiating the class into the variable declaration, sometimes when the Singleton object has a lot of overhead and may or may not be used in your application, you should use lazy load and the best way to do it is by exploiting the 'volatile' keyword which ensures that the JVM supplies the latest version of Singleton within the Synchronized code.
public class Singleton {
private static volatile Singleton s;
private Singleton()
{
}
public static Singleton getInstance()
{
if(s == null)
{
synchronized(Singleton.class)
{
if(s==null)
{
s = new Singleton();
}
}
}
return s;
}
}
Here is an elegant implementation in Java with thread safety and lazy loading.
package com.journaldev.singleton;
public class BillPughSingleton {
private BillPughSingleton(){}
private static class SingletonHelper{
private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}
public static BillPughSingleton getInstance(){
return SingletonHelper.INSTANCE;
}
}
volatile boolean created;
- JDev March 07, 2013SingletonObject object;
getInstance()
{
if(object == null)
{
synchronized(obj)
{
//Make sure object is not created already
if(object == null && !creating)
{
object = new SingletonObject();
created = false;
}
//Note this is a DCL implementation. This prevents from creating the object twice by two different threads.
}
}
else
{
return object;
}
}