[concurrency-interest] Parametric Initialization On Demand Holder Idiom ?

Hanson Char hanson.char at gmail.com
Thu Aug 30 18:57:14 EDT 2007


Similar to the Initialization On Demand Holder Idiom (IODHI), 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 from "out-of-thin-air".)

The API would be something like:

    SomethingMore singleton = SomethingMore.getInstance(params);

Now this begs the question: similar to the original IODHI, can the
implementation of such "Parametric IODHI" be thread-safe without
explicit synchronization ?

See below for one proposed yet potentially controversial
implementation.  (I know I could have used ThreadLocal to eliminate
the controversy, but then it seems unnecessary and relatively
expensive.)

Any comment on it's thread-safeness and/or correctness ?  Better ideas
?  Or maybe this is completely mis-guided ?

Hanson Char

/**
 * Parametric Initialization On Demand Holder Idiom,
  * which is thread-safe yet incorrectly synchronized.
 */
public class SomethingMore
{
    /** A thread-safe 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 thread-safe value used to initialize
     * the singleton instance of SomethingMore.
     *
     * Technically data race can occur among the multiple writes to and the
     * single read from this field, and therefore it is considered
     * "incorrectly synchronized" according to the JMM.
     * Yet it doesn't matter in this case.  Or does it ?
     */
    private static Object valueHolder;
    private static class LazySomethingMoreHolder {
        public static SomethingMore something = new SomethingMore(valueHolder);
    }
    /**
     * Returns the singleton instance of {@link SomethingMore}.
     *
     * @param value a thread-safe value used to initialize the
     * singleton instance of SomethingMore, 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 per se,
     * such as a {@link String} instance.
     */
    public static SomethingMore getInstance(Object value) {
        SomethingMore.valueHolder = value;
        return LazySomethingMoreHolder.something;
    }
}


More information about the Concurrency-interest mailing list