Hot Posts

Singleton Pattern

Java EE Singleton Design Pattern

OK let’s have a look at our first pattern.

The singleton pattern is one of the most well-known design patterns and is used extensively by frameworks such as Spring, pool mangers and loggers.

If you read the GoF book, it’s about having a single instance of an object in the JVM which is only ever instantiated once within the life-cycle of the application. Once created it is not normally destroyed until the application terminates. Why do you need this? The GoF motivation was that heavy weight objects, that you would not want to create because they are expensive to have around, are created by the singleton.

If you have read any further in the GoF book, implementing the singleton pattern is quite none trivial. You have to start with some pretty unnatural constructs like private constructors, double locking and the like and in the end you still didn’t get thread safety. You need to think about thread safety as it’s a single instance being shared across the JVM and across multiple threads.

Java EE offers an elegant and easy way to implement the singleton pattern.

Singleton Pattern in Code

@DependsOn("DatabaseConnectionBean")
@Startup
@Singleton
public class Logger {

    @PostConstruct
    void constructExpensiveObject() {
        // Expensive construction
    }

}

@Inject
Logger logger;

@Singleton

The creation of the singleton class is done by the container and the container knows to create only one instance because the class is annotated with the @Singleton stereotype annotation. By default this object is read locked. Access to it is serialized, so you don’t have to worry about thread safety at all. So if two threads attempt to access the instance they will be forced into serialized access.

The container creates an instance of the Logger class and will inject the same instance wherever it finds an injection point. Injection points are annotated @Inject.

@PostConstruct

Let’s get to the expensive construction part. Remember this was one of the principle motivators of the design pattern and why you would want to have the singleton in the first place. We do this by adding the @PostConstruct annotation to the method that constructs the object. This is invoked at application start up.

@Startup

By default the singleton bean is initialized lazily: it won’t be created until first use. Normally this is sufficient for most use case scenarios, however you may want the singleton bean to perform application start up tasks in which case you must annotate the bean with @Startup: something that is not elegantly available in the classical implementation of this pattern. The container must ensure that the bean is initialized before it delivers client requests.

@DependsOn

The instantiation of your bean may depend on the initialisation of other beans. We can specify the bean on which we depend.

Conclusions so far

Already we have seen how the Java EE implementation of the singleton pattern is markedly different to its classical implementation and requires substantially less code to achieve the same results. You have been given more control over when the bean is instantiated, either at application start up or on first use, and you can specify its dependency on other beans successful instantiation. These new features enhance the behaviour and performance of the singleton bean.

But we can go further.

Now let’s look at how Java EE gives you even greater control over the pattern’s behaviour.

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class Logger {

    @AccessTimeout(value = 30, unit=TimeUnit.SECONDS)
    @Lock(LockType.WRITE)
    public void addMessage(String message) {}

    @Lock(LockType.READ)
    public String getMessage() {}
}

Remember that I mentioned that the singleton bean is thread-safe by default as concurrency is managed by the container. Well, Java EE offers two types of concurrency management: container managed and bean managed concurrency. By default the container manages the concurrency, removing the need to implement the usual concurrency solutions.

@ConcurrentManagement

However we are given the option to manage it ourselves by choosing bean managed concurrency. Add the annotation ConcurrencyManagementType.BEAN to the class definition.

We still need to be careful with method access as our bean is exposed to a concurrent environment. Two lock types control access to the beans business method: WRITE and READ.

@Lock

Methods annotated WRITE, lock to other beans while being invoked. Methods that affect change will be annotated this way. Methods annotated READ allow concurrent access.

In this code snippet, a call to the getMessage method will be forced to wait until the addMessage method completes. This may result in a ConcurrentAccessTimeoutException if the addMessage method does not complete within the specified timeout period.

@AccessTimeout

The timeout period can be configured with an annotation either at the class level or the method level.

The Good, the Bad and the Ugly

The Good

Java’s EE manner of implementing the Singleton pattern has reduced substantially the lines of boilerplate code required to achieve a tread-safe Singleton. Not only that but it adds features to our singleton that it allows to be instantiated on application start-up or on first invocation. We can make its existence depend on the successful construction of another bean.

By convention the singleton has container managed concurrency but we can take back control and manage it ourselves we can even specify an access time out value.

The Bad

Over use of singletons can cause problem with you application as can the over use of anything. Lazy loading will cause delays on first use while eager loading may cause memory problems. An instance might be created on start-up but never used or garbage collected using up memory resources.

The Ugly

The singleton pattern is often considered an anti-pattern and should be used for niche use-case scenarios. It would be smarter to use a stateless session bean.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: