Google
 
Web unafbapune.blogspot.com

Wednesday, September 26, 2007

 

Epigrams In Programming

by Alan J. Perlis

 

Perfection

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. - Antoine de Saint-Exupery (1900-1944)

Saturday, September 01, 2007

 

Parametric Initialization On Demand Holder Idiom

Similar to the Initialization On Demand Holder (IODH) Idiom , it occurs to me that sometimes not only is there a need to access a singleton instance, which is lazily initialized if constructed for the first time, but also to initialize with parameters, which are ignored if the singleton instance has already been constructed. Also, if there is concurrent access to the singleton instance for the very first time, it doesn't matter from which thread the parameters are passed, as long as the parameters are specified by one of these threads (ie the parameters don't come "out-of-thin-air".) The API would be something like:
   SomethingMore singleton = SomethingMore.getInstance(params);
Now this begs the question: similar to the original IODH Idiom, can the implementation of such Parametric IODH Idiom be thread-safe without explicit synchronization ? See below for 2 proposed implementations. One requires the parameter to be immutable, and the other requires the parameter to be only thread-safe.
/**
 * Parametric Initialization On Demand Holder Idiom 1
 * - requires parameter to be immutable and thread-safe
 * even in the face of unsafe publication.
 * (Usually such immutability can be achieved via final fields.)
 *  
 * @author Hanson Char
 */
public class SomethingMore 
{
    /** 
     * An immutable value,
     * such as a {@link String} instance. 
     */
    private final Object value;
    private SomethingMore(Object value) { this.value = value; }
    public Object getValue() { return value; }

    /** 
     * A temporary buffer to hold the immutable value used to initialize 
     * the singleton instance of SomethingMore.
     * Note it is an unsafe publication, but that's ok as 
     * the immutable value passed in is required to be thread-safe even
     * in the face of unsafe publication.
     */
    private static Object valueHolder;
    private static class LazySomethingMoreHolder {
        public static SomethingMore something = new SomethingMore(valueHolder);
    }
    
    /**
     * Returns the singleton instance of {@link SomethingMore}.
     * 
     * @param value an immutable value used to initialize the 
     * singleton instance of SomethingMore, if the instance is 
     * constructed for the first time;  
     * ignored otherwise.  
     * Note immutability (ie lack of mutator methods) 
     * itself is not sufficient.
     * The immutable value must be thread-safe even
     * in the face of unsafe publication.
     * (Usually such immutability can be achieved via final fields.)
     * Caller of this method is responsible for passing in a
     * value which is immutable and thread-safe even in the
     * face of unsafe publication,
     * such as a {@link String} instance. 
     */
    public static SomethingMore getInstance(Object value) {
        SomethingMore.valueHolder = value;
        return LazySomethingMoreHolder.something;
    }
}
/**
 * Parametric Initialization On Demand Holder Idiom 2
 * - requires parameter to be thread-safe.
 * 
 * @author Hanson Char
 */
public class SomethingMoreSafe 
{
    /** A thread-safe value, such as a {@link String} instance. */
    private final Object value;
    private SomethingMoreSafe(Object value) { this.value = value; }
    public Object getValue() { return value; }
    
    private static final ThreadLocal<Object> tlocal = new ThreadLocal<Object>();
    private static class LazySomethingMoreSafeHolder {
        public static SomethingMoreSafe something = new SomethingMoreSafe(tlocal.get());
    }

    /**
     * Returns the singleton instance of {@link SomethingMoreSafe}.
     * 
     * @param value a thread-safe value used to initialize the 
     * singleton instance of SomethingMoreSafe, if the instance is 
     * constructed for the first time;  
     * ignored otherwise.
     * Caller of this method is responsible for passing in a
     * value which is thread-safe, 
     * such as a {@link String} instance. 
     */
    public static SomethingMoreSafe getInstance(Object value) {
        tlocal.set(value);
        try {
            return LazySomethingMoreSafeHolder.something;
        } finally {
            tlocal.remove();
        }
    }
}
Special thanks to Joe Bowbeer, David Holmes, Dhanji R. Prasanna and Jeremy Manson for their help in the JSR-166 concurrency forum. More discussion can be found here.

This page is powered by Blogger. Isn't yours?