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

Joe Bowbeer joe.bowbeer at gmail.com
Thu Aug 30 19:45:46 EDT 2007


The value is not safely published here:

SomethingMore.valueHolder = value;

That creates a window where another thread could overwrite valueHolder
before the current thread initializes the singleton.

This is OK for super-safe values like String.  Immutable objects with
all fields final do not require safe publication.  In general,
thread-safe values do require safe publication.

--Joe

On 8/30/07, Hanson Char <hanson.char at gmail.com> wrote:
> 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