The simplest way to define a singleton in Java correctly

A singleton pattern is probably the simplest well-known design pattern, but still people often implement it incorrectly in Java.

The main goal of the pattern is to ensure there is a single instance of a class accessible globally before it is first needed.

But wait, that could be accomplished just by a constant, right? Almost. But in reality, we often want to load the singleton lazily at the point we first need it, and we also want to ensure that it is not created multiple times in multi-threaded environments.

I’ve seen crazy complex solutions like this one to do it correctly. I mean, they are correct, but just too complex to implement by hand without a mistake. They are applicable in any language but they don’t take into account how JVM works to simplify the solution.

My point is that JVM classloaders already provide both lazy loading and thread-synchronization. Contrary to popular beliefs like that all classes are loaded at start-up or when imported by another class, they are loaded when their bytecode is executed.

Therefore it is only necessary to define a Singleton class that includes the constant – the static field will be only initialized once the class is loaded, and that would be when Singleton.INSTANCE is first accessed.

It is even simpler to use Java enum to implement the constant. Enums also bring additional advantage because enum values remain single even after deserialization, whereas class instances are deserialized as new instances.

You may access the singleton as easy as:

 

In practice, it is better to provide a getter method for the field, so that the access can be intercepted if needed later. But it is not really necessary.

Note that this approach is not a new idea and it is also recommended by the Effective Java by J. Bloch. However, you often won’t find out that this pattern really loads the singleton lazily, not even in the Bloch’s book. There is no need to implement additional lazy loading and reinvent the wheel when the JVM does it for us and does it correctly even in a multi-threaded environment.

Therefore the core message from me is: there is no need to ensure additional lazy loading and synchronized access to the constructor. The JVM does it for us and does it correctly!

3 thoughts on “The simplest way to define a singleton in Java correctly

  1. Singleton is anti-pattern
    Because of people quality it is better not to do so
    People common use the singleton as silver bullet solution which later on lead to problems, especially when the maintenance team are not same coders as the prime coders on beginning. After few years it is pain to change or even improve the architecture.

    1. Thanks Peter for your comment. I agree that when dependency injection is available, it is better to use it to provide instances than getting them as singletons. I wouldn’t say that singleton is antipattern, but there are much better ways to implement it if you have the options. For example, CDI offers @ApplicationScoped, which will inject singleton beans, but providing control over how the bean is created without changing the code which uses it.

      The aim of my blog post was to provide a simple and working solution for plain Java if better options are not available. I’ve seen people using lot more code to implement it incorrectly, and even more code to finally fix it.

  2. Food for thought – “In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object.” (wikipedia). What you are writing about is a singleton on the JVM level. Specifically for a single ClassLoader. What if the application uses multiple ClassLoaders (as application servers usually do; or any clustered application running across multiple JVMs …). Singleton pattern is one of the simplest patterns. But you can stretch it and make the implementation as complicated as you want to 😀

Leave a Reply

Your email address will not be published. Required fields are marked *