Thread Safe Singleton Class

Thread Safe singleton class

You are implementing the lazy initialization pattern - where the instance is created when first used.

But there is a simple trick that allows you to code a threadsafe implementation that doesn't require synchronization! It is known as the Initialization-on-demand holder idiom, and it looks like this:

public class CassandraAstyanaxConnection {

private CassandraAstyanaxConnection(){ }

private static class Holder {
private static final CassandraAstyanaxConnection INSTANCE = new CassandraAstyanaxConnection();
}

public static CassandraAstyanaxConnection getInstance() {
return Holder.INSTANCE;
}
// rest of class omitted
}

This code initializes the instance on the first calling of getInstance(), and importantly doesn't need synchronization because of the contract of the class loader:

  • the class loader loads classes when they are first accessed (in this case Holder's only access is within the getInstance() method)
  • when a class is loaded, and before anyone can use it, all static initializers are guaranteed to be executed (that's when Holder's static block fires)
  • the class loader has its own synchronization built right in that make the above two points guaranteed to be threadsafe

It's a neat little trick that I use whenever I need lazy initialization. You also get the bonus of a final instance, even though it's created lazily. Also note how clean and simple the code is.

Edit: You should set all constructors as private or protected. Setting and empty private constructor will do the work

Thread safe singleton, locks

The best performing and thread-safe Singleton implementation is the William Pugh Singleton. You don't need synchronized blocks and ReentrantReadWriteLock.

The William Pugh implementation ensures multi-thread safety and the best performances as it avoids eager creation. In fact, the static member INSTANCE, initialized at class level, will be created only when the nested class is loaded by the class loader, i.e. when the nested class will be actually used. In the following implementation, this can only happen when the getInstance() method is invoked. In fact, conversely from the EagerSingleton, this model actually allows using the enclosing class without causing an eager instantiation. This means that any other method offered by the enclosing class can be safely used without initializing INSTANCE; only the getInstance() method will cause it.

Your implementation could look like this:

class JsonWriter {

private JsonWriter() {}

/* ... other methods ... */

public static JsonWriter getInstance() {
return SingletonHelper.INSTANCE;
}

private static class SingletonHelper {
private static final JsonWriter INSTANCE = new JsonWriter();
}
}

A particular thanks to @Holger, who contributed with important clarifications and remarks in the comments.

Thread Safe Singleton Class - Am I doing this Right?

Yours is not idiomatic singleton, because it is still prone to so-called "static initialization order fiasco".

An idiomatic singleton doesn't have a static class member, instead it's instance function looks like

static MySingleton& instance() {
static MySingleton the_ton;
return the_ton;
}

More on the fiasco: static initialization order fiasco

What does it exactly mean if a Singleton is not thread-safe?

More instances can possibly exist if you're unlucky enough that it is accessed at the same time so both threads get past the if(INSTANCE == null) at the same time.

That is why you typically instead do

public final class ClassSingleton {

private static volatile ClassSingleton INSTANCE;
private String info = "Initial info class";

private ClassSingleton() {
}

private static final Object lock = new Object();

public static ClassSingleton getInstance() {
if(INSTANCE == null) {
synchronized(lock) {
if(INSTANCE == null) {
INSTANCE = new ClassSingleton();
}
}
}

return INSTANCE;
}

// getters and setters
}

As it forces a thread to wait if there is already another thread inside the monitor of lock, initializing the singleton.

(EDIT: also, i'm glad the duplicate question is "why to use volatile", I figured it should be necessary so I added it :p otherwise the other thread wouldn't see immediate changes to this shared variable. Another option instead of volatile would be to use AtomicReference<T>.)

Thread safe singleton in swift

Thanks to @rmaddy comments which pointed me in the right direction I was able to solve the problem.

In order to make the property foo of the Singleton thread safe, it need to be modified as follows:

    class Singleton {

static let shared = Singleton()

private init(){}

private let internalQueue = DispatchQueue(label: "com.singletioninternal.queue",
qos: .default,
attributes: .concurrent)

private var _foo: String = "aaa"

var foo: String {
get {
return internalQueue.sync {
_foo
}
}
set (newState) {
internalQueue.async(flags: .barrier) {
self._foo = newState
}
}
}

func setup(string: String) {
foo = string
}
}

Thread safety is accomplished by having a computed property foo which uses an internalQueue to access the "real" _foo property.

Also, in order to have better performance internalQueue is created as concurrent. And it means that it is needed to add the barrier flag when writing to the property.

What the barrier flag does is to ensure that the work item will be executed when all previously scheduled work items on the queue have finished.

Is this code correct example of thread safe Singleton design pattern?

This is guaranteed to be safe by the JLS. See the holder pattern: "since the class initialization phase is guaranteed by the JLS to be sequential, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization."

The holder pattern is more complex than what you want, but the important part is that static final Something INSTANCE = new Something() is safe no matter which class it is declared in. The benefit of the holder pattern compared to what you have is that the singleton won't be initialized until the first time it is used. This is helpful if you want to access other static members in your Singleton class when the cost of initializing the Singleton instance is expensive.

As Lewis_McReu and user6690200 pointed out, you should declare the INSTANCE field final in order to ensure that you don't accidentally assign a different Singleton instance to the variable. You should also declare a private no-argument Singleton() constructor to prevent other instances from being created. To make it even more bulletproof, you should declare the Singleton class final so that you can't subclass it with a public constructor.

Why is this singleton implementation not thread safe?

I suggest you choose a better singleton implementation. The metaclass-based implementation is the most elegant in my opinion.

As for for thread-safety, neither your approach nor any of the ones suggested in the above link are thread safe: it is always possible that a thread reads that there is no existing instance and starts creating one, but another thread does the same before the first instance was stored.

You can use a with lock controller to protect the __call__ method of a metaclass-based singleton class with a lock.

import threading

lock = threading.Lock()

class Singleton(type):
_instances = {}

def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
with lock:
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]

class SingletonClass(metaclass=Singleton):
pass

As suggested by se7entyse7en, you can use a check-lock-check pattern. Since singletons are only created once, your only concern is that the creation of the initial instance must be locked. Although once this is done, retrieving the instance requires no lock at all. For that reason we accept the duplication of the check on the first call so that all further call do not even need to acquire the lock.

When using the singleton design pattern, do other methods need to use synchronized keyword to ensure thread safety?

First, a Singleton pattern is best implemented as Enum in Java
Second, each email manipulation function (clear, Recycle, delete) should be synchronized to ensure thread safety (the link is about an Enum, but the same holds about each and every Sinlgeton implementation):

public synchronized void RecycleEmail(Email email)


Related Topics



Leave a reply



Submit