Personal Workflow Blog

To content | To menu | To search

java

Some random thoughts collected meanwhile working on an Enterprise-grade J2EE stack.

Entries feed

Saturday, 26 May 2007

Avoid the runtime penaly of Singletons

A common way to do the Singleton pattern involves a getInstance() method which does a runtime test like this :

private static Singleton instance;
private static Object mutex;

public static Singleton getInstance() {
        if (null == instance) {
                // First call
                synchronized (mutex) {
                        if (null == instance) {
                                instance = new Singleton ();
                        }
                }
        }
        return instance;
}

private Singleton() {
}

This method works well, since it uses the double-null-check. You always have to check it while beeing under a synchronized belt, and you check it just before in order to avoid the synchronized cost after its initialisation. So we have a method that still makes a runtime check, and cannot be nicely inlined by the compilator.

If you can afford to :

  • not be able to deregister the instance afterwards with a freeInstance() method (We'll speak about this later)
  • not defering the creation of the instance the first time you need it (also called lazy creation)

you can avoid that extra cost by creating the instance in class loading time with a static block.

The code then becomes :

public static Singleton getInstance() {
        return instance;
}

private Singleton() {
}

private static Singleton instance = new Singleton();

The getInstance() method can now be inline quite easily and there is no more extra check cost. Note that here the default constructor is empty. If it's not, I suggest to put the static initialisation at the end of the class, in order for the rest of the class to be initialised and to be ready for use in the constructor.

If you want to be able to deregister you have to use the first version, and write a freeInstance() like :

public static void freeInstance() {
        if (null != instance) {
                // First call
                synchronized (mutex) {
                        if (null != instance) {
                                // Do some closing work here if required like instance.close()
                                instance = null;
                        }
                }
        }
}

And now you just wrote a primitive form of pooling (with only one instance)..But that's another story...

Monday, 19 March 2007

Inheritance of a public method considered harmful

I'm always wondering why all textbooks and reference material on the web always describe inheritance with the same kind of example :

class A {
        public execute() {
                // do something...
        }
}
class B extends A {
        public execute() {
                // initialize for B
                super.execute();
        }
}
class C extends A {
        public execute() {
                // initialize for B
                super.execute();
        }
}

One thing struck me : if I want to have some code executed before execute() in every class, such as preparing the graphic context for example, I have to write a protected method initializeContext() on the base class and call it from every derived execute() method. This is a good candidate for errors since it's manual and therefore not automatic.

I prefer to go for an IoC-like inheritance scheme, we could call it "Inversion of Inheritance". The code would be something like :

class A {

   protected executePre() {
                // Default implementation 
                // does nothing
        }
   protected executePost() {
                // Default implementation 
                // does nothing
        }
   protected executeInternal()     {
                // do something
        }
        
        public final execute() {
                executePre();
                executeInternal();
                executePost();
        }
}
class B extends A {
        protected executeInternal() {
                // initialize for B
        }
}
class C extends A {
        protected executeInternal() {
                // initialize for C
        }
}

There are 2 problems with this approach :

  1. There is a little performance penalty since every calls issues 3 virtual calls.
  2. If you want to add another interception function, you have to edit the base class.

But the main purpose is that you are in control of the derived classes of your class since the creativity of the reuser is severly hampered. I think of it as the most easy way to enforce the Liskov substitution principle.

page 3 of 3 -