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 thegetInstance()
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
Why Shouldn't You Extend Jframe and Other Components
Java Dynamic Binding and Method Overriding
Java:Why Should We Use Bigdecimal Instead of Double in the Real World
Jsf Convertdatetime Renders the Previous Day
What Is the Convention for Word Separator in Java Package Names
Debug a Java Application Without Starting the Jvm with Debug Arguments
How to Extract Cn from X509Certificate in Java
Java.Lang.Nullpointerexception Is Thrown Using a Method-Reference But Not a Lambda Expression
Garbage Collector in Java - Set an Object Null
Converting a Java Keystore into Pem Format
How to Generate the JPA Entity Metamodel
File Upload with Java (With Progress Bar)
How to Open a File with the Default Associated Program
How to Configure Jackson in Wildfly
Maven Is Not Working in Java 8 When Javadoc Tags Are Incomplete