Double-checked locking with Singleton pattern in Java

I just faced problem with synchronization many threads starting at the same time (with microseconds difference) and creating single object instance of connection to the database using a Singleton Pattern in Java. As a result I had many connections except one. The sent queries counter has been set to smaller value as excepted in simulations.

I have just Google’d the IBM article by Peter Haggar, Senior Software Engineer “Double-checked locking and the Singleton pattern”.

Problem overview

Creating an singleton in Java is simple to implement. There are two common ways to create singleton:

  1. Lazy loaded with create an private static field _instance filled by null (by default Java object initialization). The instance is created, when the static method getInstance() is called.
  2. Create an class instance in advance, just before class is loaded to memory by declaring a value of priate static field _instance by calling the private constructor new SingletonClass();

1st implementation with lazy initialization

package pl.athlan.examples.singleton;
 
public class Singleton {
	private static Singleton _instance; // null by default
 
	private Singleton() {
	}
 
	public static Singleton getInstance() {
		if(_instance == null) {
			_instance = new Singleton();
		}
 
		return _instance;
	}
}

2nd implementation with eager initialization

package pl.athlan.examples.singleton;
 
public class Singleton {
	private static Singleton _instance = new Singleton(); // object is created just after class is loaded into memory
 
	private Singleton() {
	}
 
	public static Singleton getInstance() {
		return _instance;
	}
}

Motivation.

Imagine two separated threads with is delegated to call getInstance() method at the same time.

Thread #1 Thread #2 value of _instance
Singleton.getInstance() null
Singleton.getInstance() null
if(_instance == null) null
if(_instance == null) null
_instance = new Singleton() [object #1]
_instance = new Singleton() [object #2]

As a result, two object has been created, because thread #2 hasn’t noticed the object creation.

If your object stores common data like a (in my case) database queries counter or the creation of the object is time-expensive when the system just hang out for many threads – this situation have not to occur.

Sloving the problem.

The problem slove is to synchronize the threads while accessing getInstace method. You can simply write:

public static synchronized Singleton getInstance()

but this solution produces an huge overhead to synchronize all threads calling this method. The better solution is to synchronize the fragment of code which checks an existance and creates the object in fact, except of returing if it already exists.

Finally solution:

package pl.athlan.examples.singleton;
 
public class Singleton {
	private volatile static Singleton _instance;
 
	private Singleton() {
	}
 
	public static Singleton getInstance() {
		if(_instance == null) {
 
			// causes that this block will be processed in sequence in parallel computing mode
			synchronized(Singleton.class) {
 
				// if previous sequence created the instance, just omit object creation
				if(_instance == null) {
					_instance = new Singleton();
				}
			}
		}
 
		return _instance;
	}
}

The volatile keyword assigned to _instance field provides the synchronization.

If there is no instance of the object, the synchronized block will begin. It means that all processes are queued to access that block. After access just ensure one more time, if the single object is not exists in fact, because the process doesn’t know what happened before it has rached the queue. If any process before queueing has created the object, just ommit the creation.

Hope it helped!

NOTE: Note that implementing Singleton by an ENUM is thread-safe and reflection-safe.

 

Parallel Matrix Multiplication in ADA95

I want to share my elaboration about Parallel Matrix Multiplication I have writed (as extra task) by the way Parallel Computations which is one of my subject in Silesian University of Technology in the Computer Science course I attend. The elaboration have been written of course in Polish.

I have sloved this problem very simply in ADA95 programming language, which gives an opportunity to write parallel programs very easly in Pascal-like syntax.

My solution of this problem divides an elementary operations between 1 to N provided processors, distributed with shared memory CRCW PRAM model (Parallel Concurrent Read and Concurrent Write). In particular, you can fire up computing in only one processor. Elaborate discuss about problems with value of memory cells working as an accumulator in adding (+) process. It’s overall only.

Finally, I have compiled the code under GNAT 2011 compiler in GPS 2011 IDE (GNAT Developer Studio). For people interested in ADA95 programming and Parallel Computations I recommend some polish books avaiable for example in Silesian Libraries:

  • Porębski, W. (2003). ADA95 Wprowadzenie do Programowania. Michałowice: Komputerowa Oficyna Wydawnicza “HELP”, Piotr Gomoliński.
  • Czech, Z. (2010). Wprowadzenie do obliczeń równoległych. Warszawa: Wydawnictwo Naukowe PWN.
  • Ben-Ari, M. (2009). Podstawy Programowania współbieżnego i rozproszonego (strony 99-133). Warszawa: WNT.

Xin Wang reveals another ways to slove this problem in Scalable Parallel Matrix Multiplication Algorithms with
Application to a Maximum Entropy Problem
publication, but it is only math theory, without implementation.

You can easly write parallel prorgams using MPI library for C++ or Parallel library Java. In general, there are many ways to implement algorythms, but the most important in Parallel Computations is not implementations, but problem decomposition and hardware structure of computing processors which exchanges information with each other.

Have fun!