Pages

Thursday 30 January 2014

Singleton Pattern in Java



Definition:

The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects

  • Ensure that only one instance of a class is created.
  • Provide a global point of access to the object.

UML Diagram:



Implementation:

There are many Implementations of the Singleton pattern in java, lets have a look at all.

1. Using ENUM:


Joshua Bloch explained this approach in his Effective Java Reloaded talk at Google I/O 2008: link to video. Also see slides 30-32 of his presentation (effective_java_reloaded.pdf):


enum Singleton {
 INSTANCE;
 private final String[] favoriteBooks = { "Effective java", "Java Concurrency" };
 public void printFavorites() {
  System.out.println(Arrays.toString(favoriteBooks));
 }
}

According to Joshua Bloch: "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."

This implementation will:
  • Work in Multi-threaded environment without synchronizing it.
  • Provides the serialization machinery for free,

2. Lazy Initialization Holder Class/Initialization-on-demand holder idiom


In this technique we create a static class holder  which will return the singleton instance. It uses the Java class initialization guarantee where the static class holder will not get initialized till it is been referenced.This implementation is a well-performing and concurrent implementation valid in all versions of Java.


public class Something implements Serializable {
 private Something() {}
 
 private static class LazyHolder {
  private transient static final Something INSTANCE = new Something();
 }
 
 public static Something getInstance() {
  return LazyHolder.INSTANCE;
 }
 
 protected Object readResolve() {
  return Something.getInstance();
 }
}

  • The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class. 
  • It is not sufficient merely to add implements Serializable to its declaration. To maintain the singleton guarantee, you have to declare all instance fields transient and provide a readResolve method. Otherwise, each time a serialized instance is deserialized, a new instance will be created.
  • Use this pattern if the initialization of the class is expensive and it cannot be done safely at class-loading time and the initialization is concurrent. .

3. Eager initialization


In the following implementattion the singleton object is instantiated when the class is loaded and not when it is first used, due to the fact that the instance member is declared static. This is why we don't need to synchronize any portion of the code in this case.


public class Singleton implements Serializable {
 private transient static final Singleton instance = new Singleton();

 private Singleton() {}
 public static Singleton getInstance() {
  return instance;
 }
 protected Object readResolve() {
  return instance;
 }
}

4. Lazy initialization


In this implementation the Singleton object is instantiated lazily only when getInstance method is called.

class Singleton implements Serializable {
 private transient static Singleton instance;
 private Singleton() { }
 public static Singleton getInstance() {
  if (instance == null) {
   instance = new Singleton();
  }
  return instance;
 }
 protected Object readResolve() {
  return Singleton.getInstance();
 }
}

  • This implementation will not work in Multi-Threaded environment. Use the below implementation to work with multi threaded environment.

5. Lazy initialization - Synchronized


This is Synchronized version of the Lazy Initialization technique to work in Multi-threaded environment.

class Singleton implements Serializable {
 private transient static Singleton instance;
 private Singleton() { }
 public static synchronized Singleton getInstance() {
  if (instance == null) {
   instance = new Singleton();
  }
  return instance;
 }
 protected Object readResolve() {
  return Singleton.getInstance();
 }
}

Using the synchronized keyword in this way will be extremely costly, because it's acted upon every time the getInstance() method is invoked. There is a different technique to avoid performance bottlenecks in applications, and this is to modify the code to synchronize only the assignment in the getInstance() method.

6. Double-checked locking


Double-checked locking used to reduce the overhead of acquiring a lock by first testing the locking criterion without actually acquiring the lock. Only if the locking criterion check indicates that locking is required does the actual locking logic proceed.


public class Singleton implements Serializable {
 private transient static Singleton instance;
 private Singleton() { }
 public static Singleton getInstance() {
  if(instance == null) {
   synchronized(Singleton.class) {
    if (instance == null) {
     instance = new Singleton();
    }
   }
  }
  return instance;
 }
 protected Object readResolve() {
  return Singleton.getInstance();
 }
}

Applicability & Examples

  • Logger Classes: The Singleton pattern is used in the design of logger classes. This classes are ussualy implemented as a singletons, and provides a global logging access point in all the application components without being necessary to create an object each time a logging operations is performed.
  • Configuration Classes: The Singleton pattern is used to design the classes which provides the configuration settings for an application. By implementing configuration classes as Singleton not only that we provide a global access point, but we also keep the instance we use as a cache object. When the class is instantiated( or when a value is read ) the singleton will keep the values in its internal structure. If the values are read from the database or from files this avoids the reloading the values each time the configuration parameters are used.
  •  Accessing resources in shared mode: It can be used in the design of an application that needs to work with the serial port. Let's say that there are many classes in the application, working in an multi-threading environment, which needs to operate actions on the serial port. In this case a singleton with synchronized methods could be used to be used to manage all the operations on the serial port.
  • Factories implemented as Singletons: Let's assume that we design an application with a factory to generate new objects(Acount, Customer, Site, Address objects) with their ids, in an multithreading environment. If the factory is instantiated twice in 2 different threads then is possible to have 2 overlapping ids for 2 different objects. If we implement the Factory as a singleton we avoid this problem. Combining Abstract Factory or Factory Method and Singleton design patterns is a common practice.

Wednesday 29 January 2014

Use of Volatile variable w.r.t. to Synchronization

I'm going to talk about what volatile means in Java. First, you have to understand the Java memory model. And what would be the best way then reading the JLS itself. See here: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4

Take away from the Java memory Model is that the Java programming language allow compilers and microprocessors to perform optimizations on your code i.e.
  1. Can reorder your statements/instructions. A Just-In-Time compiler in a Java Virtual Machine implementation may rearrange code, or the processor.
  2. Perform Forward Substitution to optimize your code.
One of important statement from the JLS: To determine if the actions of thread t in an execution are legal, we simply evaluate the implementation of thread t as it would be performed in a single-threaded context, as defined in the rest of this specification. 


Consider an example:

class VolThread implements Runnable {
 private boolean stop = false;

 public void stop() {
  stop = true;
 }

 @Override
 public void run() {
  while (!stop) {
   try {
    Thread.sleep(100);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.out.println("Running");
  }
 }
}

public class VolTest {
 public static void main(String[] args) {
  VolThread vt = new VolThread();
  Thread t1 = new Thread(vt);
  Thread t2 = new Thread(vt);
  t1.start();
  t2.start();
  vt.stop();
 }
}

In the normal scenario both the threads would get complete as soon as vt.stop has been called. However it is perfectly valid to say that JMM can optimize your code and just replace the while condition block with an infinite block. As JMM can see that your are reading the value of stop variable to decide whether to continue the while block and the value of that variable is not going to change in that Thread t so it can optimize your code and just replace it with the infinite loop. That is an Issue!! And your code is not properly syncronized.

What do you mean by incorrectly synchronized?


When we talk about incorrectly synchronized code in the context of the Java Memory Model, we mean any code where
  1. There is a write of a variable by one thread,
  2. There is a read of the same variable by another thread and
  3. The write and read are not ordered by synchronization
When these rules are violated, we say we have a data race on that variable. A program with a data race is an incorrectly synchronized program.
 
Java allows threads to access shared variables and to ensure that shared variables are consistently and reliably updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that enforces mutual exclusion for those shared variables.

So the above scenario can be handled by:
  1. Using locks
  2. Declaring the stop variable as Volatile
What does Volatile variable do?
  • Reads and writes to the volatile variable go directly to memory i.e. it is not cached.
  • Reads and write of volatile variable cannot be reordered.
  • Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire.
  • Java Memory Model ensures that all threads see a consistent value for the variable.
  • A write to a volatile field happens-before every subsequent read of that same volatile field.
Corrected code with volatile variable:

class VolThread implements Runnable {
 private volatile boolean stop = false;

 public void stop() {
  stop = true;
 }

 @Override
 public void run() {
  while (!stop) {
   try {
    Thread.sleep(100);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.out.println("Running");
  }
 }
}

public class VolTest {
 public static void main(String[] args) {
  VolThread vt = new VolThread();
  Thread t1 = new Thread(vt);
  Thread t2 = new Thread(vt);
  t1.start();
  t2.start();
  vt.stop();
 }
}
 
You can use volatile variables instead of locks only under a restricted set of circumstances. Both of the following criteria must be met for volatile variables to provide the desired thread-safety:
  1. Writes to the variable do not depend on its current value.
  2. The variable does not participate in invariants with other variables.

 Let me know if this makes sense.