VMWare Inc Interview Question
Java DevelopersCountry: United States
Interview Type: Phone Interview
nice example of ill-formed singleton class. Just imagine what will happen in case if 100 threads will call to this method – it will block all of them one by one just to check that singleton instance is not null.
Isn't that better than not synchronizing it and winding up with more than one instances of the class?
public class Singleton {
private static volatile transient Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
}
}
class SingleT {
private:
SingleT(){}
SingleT(const SingleT& obj){}
const SingleT& operator= (const SingleT& rhs){}
public:
static SingleT* obj;
static SingleT* creator(){
if (!obj)
{
obj = new SingleT();
}
return obj;
}
};
Obviously, I have not taken care of thread safety here. you can google it and will get easily.
a> public class SingleInst {
public static final SingleInst INSTANCE = new SingleInst();
private SingleInst() {
...
}
... // Remainder code...
}
B> // Singleton with static factory
public class SingleInst {
private static final SingleInst INSTANCE = new SingleInst();
private SingleInst() {
...
}
public static SingleInst getInstance() {
return INSTANCE;
}
... // Remainder code..
}
c> With New java version - you could use enums too..
public class Singleton
{
private static Singleton singleInstance;
static
{
singleInstance = new SingleInstance();
}
private Singleton()
{
// This can not be called
}
public Singleton getInstance()
{
return singleInstance;
}
}
Let me correct the above one:
public class Singleton
{
private static Singleton singleInstance;
static
{
singleInstance = new Singleton();
}
private Singleton()
{
// This can not be called
}
public Singleton getInstance()
{
return singleInstance;
}
}
public class Singleton {
private static final Singleton instance;
private Singleton(){}
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
As you can see, the constructor is private, so we are unable instantiate it in the normal fashion. What you have to do is call it like this:
1
public Singleton singleton = Singleton.getInstance();
When you do this, the getInstance() method then checks to see if the parameter ‘instance’ is null. If it is, it will create a new one by calling the private constructor. After that, it just returns it. Of course, if it is not null, it just returns the existing instance of it. This insures that there is only one copy of the object within your program.
CTest.hpp
#include <iostream>
class CTest {
private:
int m_nVal;
static CTest * m_pInstance;
//! Constructor.
CTest() : m_nVal(0) {
std::cout << "CTest(): " << m_nVal << std::endl;
}
//! Disable copy constructor.
CTest(const CTest&) = delete;
//! Disable assignment operator.
CTest& operator = (const CTest&) = delete;
public:
//!Distructor
~CTest() {
std::cout << "~CTest()" << std::endl;
}
static CTest& getInstance();
};
CTest.cpp
#include "CTest.hpp"
#include <mutex>
std::once_flag o_flg;
CTest* CTest::m_pInstance = NULL;
CTest& CTest::getInstance() {
call_once(o_flg, []() {
if (!m_pInstance) {
m_pInstance = new CTest();
}
}
);
return *m_pInstance;
}
main.cpp
#include "CTest.hpp"
#include <thread>
#include <vector>
void createInst() {
CTest& mInst = CTest::getInstance();
}
int main() {
{
std::vector<std::thread> tLst;
for (size_t i = 0; i < 100; i++) {
tLst.push_back(std::move(std::thread(createInst)));
}
for (auto& t : tLst) t.join();
}
std::cin.get();
return 0;
}
- nueman fernandez June 05, 2013