Question

Basing on this topic, I put down an interesting version of Singleton pattern which implementation is based on AtomicIntegers.

The questions are:

  • is this implementation correct and thread-safe, and generally is it possible to use Atomic Variables for thread synchronization and management?
  • Additional question: if this implementation is thread-safe, do I really need a volatile modifier for instance variable?
public class StrangeSingleton
{

    private StrangeSingleton() {};

    private static volatile Object instance;

    private static AtomicInteger initCounter = new AtomicInteger();
    private static AtomicInteger readyCounter = new AtomicInteger();

    static Object getInstance()
    {

        if (initCounter.incrementAndGet() == 1)
        {
            instance = new Object();

            readyCounter.incrementAndGet();

            return instance;
        }
        else if (readyCounter.get() == 1)
        {
            return instance;
        }
        else
        {
            //initialization not complete yet.
            //write here some logic you want:               
            //sleep for 5s and try one more time,
            //or throw Exception, or return null..

            return null;
        }
    }
}

UPDATE: added the private constructor, but its not the point.

Was it helpful?

Solution

is this implementation is correct and thread-safe, and generally is it possible to use Atomic Variables for thread synchronization and management?

Its is but it usually more complicated and cpu intensive as you need to busy wait to respond to changes quickly.

Additional question: if this implementation is thread-safe, do I really need a volatile modifier for instance variable?

In this case you don't because AtomicInteger contain volatile fields which will ensure correct happens-before/happens-after behaviour.


Of course you could just use an enum which is thread safe and much simpler ;)

enum Singleton {
    INSTANCE;
}

OTHER TIPS

is this implementation correct and thread-safe, and generally is it possible to use Atomic Variables for thread synchronization and management?

Yes, but for the readyCounter variable you should probably use a CountDownLatch, like this:

private static AtomicInteger initCounter = new AtomicInteger();
private static CountDownLatch readyCounter = new CountDownLatch(1);

static Object getInstance()
{

    if (initCounter.incrementAndGet() == 1)
    {
        try {
            instance = new Object();
            return instance;
        } finally {
            readyCounter.countDown();
        }
    }
    else
    {
        readyCounter.await();
        return instance;
    }
}

Calling await() also solves the initialization race condition. (I also added a try-finally block to avoid deadlocks on a constructor exception.)

Additional question: if this implementation is thread-safe, do I really need a volatile modifier for instance variable?

No, not if you call the relevant AtomicInteger or CountDownLatch functions before accessing the instance variable. Look for happens-before in the documentation.

Thread T1 may be suspended on instance = new Object();, T2 will then hit the else{} block since readyCounter hasn't been incremented yet. Thtat is not quite correct since initialization has completed, what's lagging behind is the state book-keeping

I would rather do one synchronized block in your getInstance() method. This is sufficient. You don't need these strange counters which are also not so safe as @David noticed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top