Singletons

I've read several forum postings on singletons, but still have several questions.

We initially created our singletons using eager instantiaion, but discovered that this did not work on our target hardware which is a multiprocessor machine. It seems to me that our only choice is to use a synchronized getInstance(). Are there other options?

One developer suggested that all singletons should be created in the main method before any other work or threads are created. I don't really like this idea for several reasons. It forces all creators of singletons in the future to know that they should add a getInstance call in main() (doesn't seem very object-oriented to me). As our application grows, it just seems like a lot of unnecessary overhead at start-up. Comments?

Another statement was made that singletons should never reference other singletons. Is this a valid statement? If so, how do I get around this, if in fact my singleton has a valid reason to reference another.

Thanks for any help/comments.

[1041 byte] By [teresaswarthouta] at [2007-10-2 16:40:12]
# 1

I've never like lazy instantiation of singletons. I use the code below

when I make singletons, which is from Josh Bloch's Effective Java.

It will require a little more work if you're serializing/deserializing your

singleton.

Using this template, your singleton instance will be created the

first time getInstance() is referenced. No synchronizing is necessary

unless your singleton has dynamic state and is in a multithreaded

application.

Making spurious getInstance() calls to load your singletons is

wasteful and unnecessary. I don't see any reason why a singleton

should/should not reference other singletons if it needs to, in general.

I'd be very surprised if the code below doesn't work on a multiprocessor

system, but I don't have one to do testing on. If it doesn't, can you

describe the issue? I'm curious as to why synchronization would

make any difference. Hm. Do multiprocessor systems use

multiple classloaders? That might be the issue also.

public final class MySingleton {

private final static MySingleton INSTANCE = new MySingleton();

// other class variables

private MySingleton() {

// perform class initialization

}

public MySingleton getInstance() {

return MySingleton.INSTANCE;

}

// other methods

}

es5f2000a at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

We were initially creating our singletons exactly as you described. However, when we ran on our target hardware (multiprocessor machine), we repeatedly saw instances where the first request to getInstance returned a null. After a little more research, it appeared that it was related to the multiprocessor environment. Below is a link containing a letter (about 1/2 way down) describing exactly what we were seeing.

http://www.javaworld.com/javaworld/jw-04-1999/jw-04-letters2.html

The next link describes the issue a little more thoroughly, even though it states that eager instantiation should work and in our case, it clearly did not.

http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-toolbox-p2.html

There doesn't seem to be a lot of information concerning this problem which confuses me a little (and makes me question what we saw), but we were clearly getting a null pointer returned from the getInstance() instantiated exactly as you suggest.

Thanks,

teresaswarthouta at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

It is very odd that you are seeing such a problem. The eager instantiation method should be completely safe as loading and initializing a class is inherently thread safe by guarantees in the JVM.

What platform are you running on? Namely what hardware architecture, operating system and Java version? Also, are there any custom ClassLoaders getting used? Is it a J2EE application? If so, what J2EE container is being used and what is its version?

Can you give us your exact code for the singleton, free of course of any interesting business-specific or otherwise proprietary info?

cmccorveya at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

We are using a dual-core, hyper-threaded 2.4 GHz Xeon processor, Red Hat Linux v. 9 and JVM 1.5. (nothing custom).

We are going to run a regression test later today to verify what we saw.

private final static Example _instance = new Example();

public static Example getInstance()

{

return _instance;

}

Thanks,

teresaswarthouta at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

The code you have is certainly OK and the JVM will ensure single-threaded access to the initializer for the class within each ClassLoader (usually just the one). The design is inherently safe. If it were not, huge bodies of Java code including that from Sun, IBM, BEA and Oracle would be horribly broken and unreliable.

So I wonder, what does your Singleton class's constructor is doing... Anything 'unusual'?

cmccorveya at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

I was wondering, would it make any difference?

class XYW

{

private static _instance;

static

{

_instance= new Example()

}

public static Example getInstance()

{

return _instance;

}

}

or classical?

private static _instance = null;

public static Example getInstance()

{

if(_instance == null)

return new Example();

}

hernanvotoa at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

The first option is not really any different from what the OP is doing.

The second option is not thread safe. You'd have to make the method synchronized or wrap the whole "if (_instance == null)" block in a synchronized block. I think she is trying to avoid the (fairly small) cost of the synchronized mechanism exept during initial class loading.

cmccorveya at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

> We were initially creating our singletons exactly as

> you described. However, when we ran on our target

> hardware (multiprocessor machine), we repeatedly saw

> instances where the first request to getInstance

> returned a null. After a little more research, it

> appeared that it was related to the multiprocessor

> environment. Below is a link containing a letter

> (about 1/2 way down) describing exactly what we were

> seeing.

>

> http://www.javaworld.com/javaworld/jw-04-1999/jw-04-l

> etters2.html

>

> The next link describes the issue a little more

> thoroughly, even though it states that eager

> instantiation should work and in our case, it clearly

> did not.

>

> http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-

> toolbox-p2.html

One - both of those are very old.

Two - the code in both articles is not the same as the code that you say you are following. It will happen if your code does not reflect exactly the example code above (if you try to instantiate in the method.) And that is the type of code that the two articles discuss.

Which version of the VM are you using?

jschella at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

> We initially created our singletons using eager

> instantiaion, but discovered that this did not work

> on our target hardware which is a multiprocessor

> machine. It seems to me that our only choice is to

> use a synchronized getInstance(). Are there other

> options?

My understanding was that classloading is atomic. If this is indeed what you are seeing I think your JVM is suspect.

The other thing that is questionable about this is that in most cases, a Singleton class is loaded at the same time the first call is made to the getInstance() method. In this respect, they are no more eager than lazy-loaded singletons. Only in the case where the class is loaded long before the getInstance method is used is there a appreciable difference. This happens only in special cases.

> One developer suggested that all singletons should be

> created in the main method before any other work or

> threads are created. I don't really like this idea

> for several reasons. It forces all creators of

> singletons in the future to know that they should add

> a getInstance call in main() (doesn't seem very

> object-oriented to me). As our application grows, it

> just seems like a lot of unnecessary overhead at

> start-up. Comments?

That depends. If the application is a webserver, it's probably a good idea to start up things that will be needed when requests start rolling in before they are needed. Otherwise, the first users that hit the server when it comes up are going to have a poor user experience. If the singleton loads quickley (enough) or may never be used in the execution of the app o you want to spread out the load time then lazy is the way to go.

> Another statement was made that singletons should

> never reference other singletons. Is this a valid

> statement? If so, how do I get around this, if in

> fact my singleton has a valid reason to reference

> another.

I would ask the person to explain why. There are way too many people in this industry that get away with spouting off nonsense with no one calling them on it. Maybe there's a good reason. I'm sure your whole team will benefit from hearing it.

dubwaia at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 10

> I've never like lazy instantiation of singletons. I

> use the code below

> when I make singletons, which is from Josh Bloch's

> Effective Java.

> It will require a little more work if you're

> serializing/deserializing your

> singleton.

I don't understand why so many people feel this way. What is the advantage of that over a properly synchronized singleton? It has just as much overhead if not more.

dubwaia at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

> We were initially creating our singletons exactly as

> you described. However, when we ran on our target

> hardware (multiprocessor machine), we repeatedly saw

> instances where the first request to getInstance

> returned a null.

If it's not a JVM problem and you aren't using an unsafe methodolgy, it might be that the instantiation is throwing an exception and it is getting squashed somewhere in your code.

If this is the case you may need a lazy loaded singleton.

dubwaia at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 12

> > I've never like lazy instantiation of singletons.

> I

> > use the code below

> > when I make singletons, which is from Josh Bloch's

> > Effective Java.

> > It will require a little more work if you're

> > serializing/deserializing your

> > singleton.

>

> I don't understand why so many people feel this way.

> What is the advantage of that over a properly

> y synchronized singleton? It has just as much

> overhead if not more.

OK. That was dumb. Obviously, this pattern gets rid of the contention on each call to getInstance().

dubwaia at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

Thanks to everyone who replied.

We reverted our code to using the original eager instantiation which seems to run fine now. There was a marked performance hit to using the synchronized getInstances() (we have a CPU intensive streaming video application).

We were in the middle of a delivery when we originally saw the problem, however several developers looked at the exception generated by the getInstance returning a null, so I know we weren't dreaming it. We have gone in and cleaned up quite a bit of code, so maybe there was a problem in one of the constructors we didn't see because we were in a hurry. I'm a little concerned that this will bite us again, since I don't know exactly what caused the original problem.

I will post again if we see it.

Thanks,

teresaswarthouta at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 14

> We were in the middle of a delivery when we

> originally saw the problem, however several

> developers looked at the exception generated by the

> getInstance returning a null, so I know we weren't

> dreaming it. We have gone in and cleaned up quite a

> bit of code, so maybe there was a problem in one of

> the constructors we didn't see because we were in a

> hurry. I'm a little concerned that this will bite us

> again, since I don't know exactly what caused the

> original problem.

DId you consider that the getInstance() method might have thrown a NullPointerException?

dubwaia at 2007-7-13 17:48:39 > top of Java-index,Other Topics,Patterns & OO Design...
# 15

After further investigation, we have discovered that the problem was in a circular instantiation; we would have a singleton who, in its constructor, did a getInstance() on another singleton which then did a getInstance() on the original singleton. That is why we were getting NullPointers on the getInstance() calls. Thank you for all of your help!

cmlewis1a at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...
# 16

here's my first thought on the topic:

if static initialization throws and exception, it is silent. you never find out about it.

so if

private static Example _instance = new Example()

throws some sort of exception, instance just becomes null.

any chance that this is what is happening?

- Adam

guitar_man_Fa at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...
# 17

> so if private static Example _instance = new Example()

> throws some sort of exception, instance just becomes null.

> any chance that this is what is happening?

Yes, but you can detect it using the following code

private static Singleton instance;

static

{

try

{

instance = new Singleton() ;

}

catch (InitialisationException initialisationException)

{

throw new ExceptionInInitializerError(initialisationException);

}

}

MartinS.a at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...
# 18

> After further investigation, we have discovered that

> the problem was in a circular instantiation; we

> would have a singleton who, in its constructor, did a

> getInstance() on another singleton which then did a

> getInstance() on the original singleton. That is why

> we were getting NullPointers on the getInstance()

> calls. Thank you for all of your help!

I'm having trouble imagining how this would produce a NullPointerException. It's seems that it would cause a StackOverFlow or something.

dubwaia at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...
# 19
... Is it possible to clone a singleton object. thx in advance.
Lemuriaa at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...
# 20
>Is it possible to clone a singleton object.>thx in advance.If it implements Cloneable, yes. That would pretty much defeat the purpose of having a Singleton.
dubwaia at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...
# 21
It is better if Singleton's constructor is invoked in a getInstance method. Eager initialization or calling constructor inside a static block wont help us handling any exceptions that are thrown by the constructor.
balas11a at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...
# 22

Lazy initialization:

public class Singleton {

private static Singleton singleton = null;

private Singleton() {

}

public Singleton getInstance() {

if(singleton == null) {

return getNewInstance();

} else {

return singleton;

}

}

private synchronized Singleton getNewInstance() {

if(singleton == null) {

singleton = new Singleton();

}

return singleton;

}

}

pholthuizena at 2007-7-20 23:01:23 > top of Java-index,Other Topics,Patterns & OO Design...