PreviousNext…

Singletons and Java

As a pattern, it’s probably fair to say that the singleton has fallen out of favour somewhat. It is no longer the thing in these days of dependency resolution or injection, and like anything that is easy to understand, it has been thoroughly abused over the years.

However, I still think it has its place, and the only thing that’s stopped me using it in my code is (a) perceived disdain from other developers and, (b) the amount of boiler-plate guff required in a language like Java to implement a rock-solid, thread-safe singleton. I can’t provide much solace over my first point (I’m 41, and I just don’t give a toss any more), but I can offer a soothing balm for point b.

Long-time lurkers here know that one of my most favourite coding books ever is Effective Java by Joshua Bloch. It is a fantastic read, chock-full of superb tips and tricks, and very well-thumbed like The Pragmatic Programmer and a couple of others. In 2008, Bloch gave a presentation at Google IO entitled Effective Java Reloaded. There is a lot of good stuff in there (check out the slides), but the bit that piqued my attention when researching singletons recently was this:

public enum Elvis {
    INSTANCE;
    private final String[] favoriteSongs = { "Hound Dog", "Heartbreak Hotel" };
  
    public void printFavorites() {
      System.out.println(Arrays.toString(favoriteSongs));
    }
}

How’s that for a singleton implementation? (You need Java 5 or above).

I have a large Java code base I’m profiling at the moment (more on that later), and one of the things I noticed was that a couple of my static classes (yes, I know…) were being repeatedly instantiated to the extent that this was having a significant impact on memory. Not good: the heap was getting a bit of a battering, and for large data runs the code was failing with out of memory exceptions.

OK, so some of this is just because I need to clean up my classes now that the library is code-complete (and I will), but for one of the naughty objects, I identified a classic singleton use-case. As an experiment, I implemented Bloch’s pattern above (this took me about three minutes), and then I re-ran the profiling code. I watched, incredulous, as megs and megs of heap-hogging nastiness simply never occurred, and the same exception-prone code ran to completion.

Nice.

(More discussion over at Stack Overflow: What is an efficient way to implement a singleton pattern in Java?).

Comments

  1. Damn, I thought this was going to be about dating for java developers.Steve Castledine#
  2. The enum singleton has a set of interesting edge cases. Let's say the pets you tolerate are CAT and DOG, you can use a enum for that:
    public enum Pet {
    CAT,
    DOG;

    private static Map sound = null;

    public makeSound() {
    if (Pet.sound == null) {
    Pet.loadSounds();
    }
    return sound.get(this);
    }

    private static loadSounds() {
    Pet.sound = new HashMap();
    Pet.sound.put(Pet.CAT,"miaow");
    Pet.sound.put(Pet.DOG,"bark");
    }
    }

    Stephan H. Wissel#
  3. Forgot...
    you then can call that with

    Pet.DOG.makeSound();
    Pet.CAT.makeSound();

    of course if that grows a classic class is the better optionStephan H. Wissel#
  4. Yes it’s easily tinkered-with. Be sure to read the context around this approach however. Briefly, the enum approach is designed with a single element in mind (i.e. INSTANCE in the example above):
    This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.
    From http://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=3Ben Poole#
  5. in book efective java also is written that java would be better language if final were the default modifier for variables, members and methods. Of course to think of global mutable state aka singleton as think most un-final imaginable is purely academic, without any connection with real work and plain evil perspective.

    Also that singletons generate headaches when writing unit/integration tetsts. Wheres fun, when production breaks less often?

    Also DI-frameworks already care about managing singletons, if you really believe to need them. But could you name any real world project that uses DI-frameworks these days?

    And I've lost count of days, in which suddenly creative use of enum methods and constructors of programer before me turned a day of writing dull production code into an interesting ghost train ride of java puzzlers.

    Disclaimer: I know that there is this thing called existing codebase in this world, so I am all for giving legacy code a better image.
    borat axel#
  6. Love that book too, and can also heartily recommend Fowler's Refactoring.

    The enum-as-singleton is absolutely brilliant, and I tend to use it in Domino agents to represent a profile document (usually called Configuration). As an added bonus, there is an instantiated OpenLog Object which I use from any bit of code which is squirelled in that singleton object.Andrew Magerman#
  7. Just out of interest, what are you using for profiling? I've been using the built-in visualvm, but it never got the kind of line-by-line profiling that I was expecting. I've heard good things of YourKit, but have yet to shell out the money/test it.Andrew Magerman#
  8. Andrew, I played with visualvm, but it was a bit of pain trying to do anything useful with the Domino JVM. YourKit on the other hand, just worked. I profile local running Java agents by triggering the profile call from within an “agent runner” class I keep in vanilla Eclipse, but if you run a Domino server, you can attach directly to that.

    YourKit costs a bit, but it’s an excellent tool.Ben Poole#
  9. Cheers, I was humming and hahing on whether I should get it. Now all I need is a fellow developer to persuade-me that I really, really, need a spanking new iPhone 5S if I am to do any serious mobile development. It's an honest business cost, guv.Andrew Magerman#

Comments on this post are now closed.

About

I’m a software architect / developer / general IT wrangler specialising in web, mobile web and middleware using things like node.js, Java, C#, PHP, HTML5 and more.

Best described as a simpleton, but kindly. You can read more here.

";