Monday 23 February 2009

Notes on Lecture 7 : synchronized methods

The following notes are extracts from the Sun Java specification document. They are provided here as supplementary notes to the Singleton pattern that uses a synchronized method for ensuring that there is only a single instance of the Singleton object.

"The Java programming language provides multiple mechanisms for communicating between threads. The most basic of these methods is synchronization, which is implemented using monitors. Each object in Java is associated with a monitor, which a thread can lock or unlock. Only one thread at a time may hold a lock on a monitor. Any other threads attempting to lock that monitor are blocked until they can obtain a lock on that monitor. A thread t may lock a particular monitor multiple times; each unlock reverses the effect of one lock operation.

A synchronized method automatically performs a lock action when it is invoked; its body is not executed until the lock action has successfully completed. If the method is an instance method, it locks the monitor associated with the instance for which it was invoked (that is, the object that will be known as this during execution of the body of the method). If the method is static, it locks the monitor associated with the Class object that represents the class in which the method is defined. If execution of the method's body is ever completed, either normally or abruptly, an unlock action is automatically performed on that same monitor. "


http://java.sun.com/docs/books/jls/third_edition/html/memory.html#56318

1 comment:

alzamabar said...

Just one comment here. Using synchronized for a Singleton is overkill. There are various ways to safely create a Singleton in a multi-threaded application.

1) Initialise the Singleton at class loading time. This makes sense if the Singleton is not heavy to create

private static final MyClass SINGLETON = new MyClass();

public static MyClass getInstance() {
return SINGLETON;
}

2) Similar to 1) but using static initialiser:

private static MyClass SINGLETON;

static {
SINGLETON = new MyClass();
}

3) If the Singleton is heavy to create, lazy-loading could be used instead through the use of a Singleton holder:

public class MyClass {

private static class SingletonHolder() {
private static MyClass SINGLETON = new MyClass();

public static MyClass getSingleton() {
return SINGLETON;
}

public static MyClass getInstance() {
return SingletonHolder.getSingleton();
}
}

It is guaranteed that an instance of MyClass won't be created until getInstance() is invoked


4) Since Java 5 there is a best solution to create Singletons, detailed by Joshua Bloch in 'Effective Java 2nd edition'. The solution consists in declaring the singleton as an enum, namely:

public enum MyClass /* implements ... */ {
SINGLETON;

//Other methods here...
}


//Client

MyClass singleton = MyClass.SINGLETON;

The advantages of this solution is that it "provides serialization machinery for free and it provides an ironclad guarantee against multiple instantiation [...] a single-element enum type is the best way to implement a singleton" (Effective Java, 2nd edition, Item 5, page 18)

Basically the problem with the other singletons is that when serialization occurs technically another instance may be created without taking the appropriate measures (namely declaring the implementation of Serializable, declaring all fields transient and implementing a "private Object readResolve()" method.

Regards,

M.