[concurrency-interest] Multiton pattern and double-checked locking

Aleksey Shipilev aleksey.shipilev at gmail.com
Wed Jun 8 02:48:25 EDT 2011


Hi,

One colleague of mine pointed out Multiton wikipedia article which
tries to do double-checked locking [1]. I see that code ultimately
broken for two reasons:
 a. unsynchronized HashMap.get() breaks out without proper
synchronization when another caller structurally modifies the map.
 b. there's no visibility guarantees for FooMultiton fields implied on
HashMap.put(K, V).

So, I'm trying to get my head around correct and fast Multiton
implementation. It boiled down to the code below:

public class FooMultiton {
    private static final ConcurrentMap<Object, Wrapper> instances =
new ConcurrentHashMap<>();

    private FooMultiton() {}

    public static FooMultiton getInstance(Object key) {
        FooMultiton instance = instances.get(key)
        if (instance == null) {
            // slow-path, need to atomically create
            Wrapper newWrap = new Wrapper();
            Wrapper extWrap = instances.putIfAbsent(key, newWrap);
            instance = (extWrap == null) ? newWrap.instance : extWrap.instance;
        }
        return instance;
    }

    private static class Wrapper {
        public final FooMultiton instance;

        public Wrapper(FooMultiton instance)  {
            // this code should enforce visibility of FooMultiton fields.
            // can use volatile, but apparently final field semantics
does the same thing
            // when I'm doing init in constructor
            FooMultiton t = new FooMultiton();
            t.set...();
            this.instance = t;
        }
    }

 }

Is it correct, or I'm missing something?

-Aleksey.


[1] see second code chunk, http://en.wikipedia.org/wiki/Multiton_pattern#Java


More information about the Concurrency-interest mailing list