What are some recommended approaches to achieving thread-safe lazy initialization? For instance,
// Not thread-safe
public Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
For singletons there is an elegant solution by delegating the task to the JVM code for static initialization.
public class Something {
private Something() {
}
private static class LazyHolder {
public static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
see
http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
and this blog post of Crazy Bob Lee
http://blog.crazybob.org/2007/01/lazy-loading-singletons.html
If you're using Apache Commons Lang, then you can use one of the variations of ConcurrentInitializer like LazyInitializer.
Example:
ConcurrentInitializer<Foo> lazyInitializer = new LazyInitializer<Foo>() {
#Override
protected Foo initialize() throws ConcurrentException {
return new Foo();
}
};
You can now safely get Foo (gets initialized only once):
Foo instance = lazyInitializer.get();
If you're using Google's Guava:
Supplier<Foo> fooSupplier = Suppliers.memoize(new Supplier<Foo>() {
public Foo get() {
return new Foo();
}
});
Then call it by Foo f = fooSupplier.get();
From Suppliers.memoize javadoc:
Returns a supplier which caches the instance retrieved during the first call to get() and returns that value on subsequent calls to get(). The returned supplier is thread-safe. The delegate's get() method will be invoked at most once. If delegate is an instance created by an earlier call to memoize, it is returned directly.
This can be done in lock-free manner by using AtomicReference as instance holder:
// in class declaration
private AtomicReference<Foo> instance = new AtomicReference<>(null);
public Foo getInstance() {
Foo foo = instance.get();
if (foo == null) {
foo = new Foo(); // create and initialize actual instance
if (instance.compareAndSet(null, foo)) // CAS succeeded
return foo;
else // CAS failed: other thread set an object
return instance.get();
} else {
return foo;
}
}
Main disadvantage here is that multiple threads can concurrently instantiate two or more Foo objects, and only one will be lucky to be set up, so if instantiation requires I/O or another shared resource, this method may not be suitable.
At the other side, this approach is lock-free and wait-free: if one thread which first entered this method is stuck, it won't affect execution of others.
The easiest way is to use a static inner holder class :
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
}
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
This is called double checking!
Check this http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html
If you use lombok in your project, you can use a feature described here.
You just create a field, annotate it with #Getter(lazy=true) and add initialization, like this:
#Getter(lazy=true)
private final Foo instance = new Foo();
You'll have to reference field only with getter (see notes in lombok docs), but in most cases that's what we need.
Here is one more approach which is based on one-time-executor semantic.
The full solution with bunch of usage examples can be found on github (https://github.com/ManasjyotiSharma/java_lazy_init). Here is the crux of it:
“One Time Executor” semantic as the name suggests has below properties:
A wrapper object which wraps a function F. In current context F is a function/lambda expression which holds the initialization/de-initialization code.
The wrapper provides an execute method which behaves as:
Calls the function F the first time execute is called and caches the output of F.
If 2 or more threads call execute concurrently, only one “gets in” and the others block till the one which “got in” is done.
For all other/future invocations of execute, it does not call F rather simply returns the previously cached output.
The cached output can be safely accessed from outside of the initialization context.
This can be used for initialization as well as non-idempotent de-initialization too.
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
/**
* When execute is called, it is guaranteed that the input function will be applied exactly once.
* Further it's also guaranteed that execute will return only when the input function was applied
* by the calling thread or some other thread OR if the calling thread is interrupted.
*/
public class OneTimeExecutor<T, R> {
private final Function<T, R> function;
private final AtomicBoolean preGuard;
private final CountDownLatch postGuard;
private final AtomicReference<R> value;
public OneTimeExecutor(Function<T, R> function) {
Objects.requireNonNull(function, "function cannot be null");
this.function = function;
this.preGuard = new AtomicBoolean(false);
this.postGuard = new CountDownLatch(1);
this.value = new AtomicReference<R>();
}
public R execute(T input) throws InterruptedException {
if (preGuard.compareAndSet(false, true)) {
try {
value.set(function.apply(input));
} finally {
postGuard.countDown();
}
} else if (postGuard.getCount() != 0) {
postGuard.await();
}
return value();
}
public boolean executed() {
return (preGuard.get() && postGuard.getCount() == 0);
}
public R value() {
return value.get();
}
}
Here is a sample usage:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
/*
* For the sake of this example, assume that creating a PrintWriter is a costly operation and we'd want to lazily initialize it.
* Further assume that the cleanup/close implementation is non-idempotent. In other words, just like initialization, the
* de-initialization should also happen once and only once.
*/
public class NonSingletonSampleB {
private final OneTimeExecutor<File, PrintWriter> initializer = new OneTimeExecutor<>(
(File configFile) -> {
try {
FileOutputStream fos = new FileOutputStream(configFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw);
return pw;
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
);
private final OneTimeExecutor<Void, Void> deinitializer = new OneTimeExecutor<>(
(Void v) -> {
if (initializer.executed() && null != initializer.value()) {
initializer.value().close();
}
return null;
}
);
private final File file;
public NonSingletonSampleB(File file) {
this.file = file;
}
public void doSomething() throws Exception {
// Create one-and-only-one instance of PrintWriter only when someone calls doSomething().
PrintWriter pw = initializer.execute(file);
// Application logic goes here, say write something to the file using the PrintWriter.
}
public void close() throws Exception {
// non-idempotent close, the de-initialization lambda is invoked only once.
deinitializer.execute(null);
}
}
For few more examples (e.g. singleton initialization which requires some data available only at run-time thus unable to instantiate it in a static block) please refer to the github link mentioned above.
Thinking about lazy initialization, I would expect getting a "almost real" object that just decorates the still not initialized object.
When the first method is being invoked, the instance within the decorated interface will be initialized.
* Because of the Proxy usage, the initiated object must implement the passed interface.
* The difference from other solutions is the encapsulation of the initiation from the usage. You start working directly with DataSource as if it was initialized. It will be initialized on the first method's invocation.
Usage:
DataSource ds = LazyLoadDecorator.create(dsSupplier, DataSource.class)
Behind the scenes:
public class LazyLoadDecorator<T> implements InvocationHandler {
private final Object syncLock = new Object();
protected volatile T inner;
private Supplier<T> supplier;
private LazyLoadDecorator(Supplier<T> supplier) {
this.supplier = supplier;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (inner == null) {
synchronized (syncLock) {
if (inner == null) {
inner = load();
}
}
}
return method.invoke(inner, args);
}
protected T load() {
return supplier.get();
}
#SuppressWarnings("unchecked")
public static <T> T create(Supplier<T> factory, Class<T> clazz) {
return (T) Proxy.newProxyInstance(LazyLoadDecorator.class.getClassLoader(),
new Class[] {clazz},
new LazyLoadDecorator<>(factory));
}
}
Put the code in a synchronized block with some suitable lock. There are some other highly specialist techniques, but I'd suggest avoiding those unless absolutely necessary.
Also you've used SHOUTY case, which tends to indicate a static but an instance method. If it is really static, I suggest you make sure it isn't in any way mutable. If it's just an expensive to create static immutable, then class loading is lazy anyway. You may want to move it to a different (possibly nested) class to delay creation to the absolute last possible moment.
Depending on what you try to achieve:
If you want all Threads to share the same instance, you can make the method synchronized. This will be sufficient
If you want to make a separate INSTANCE for each Thread, you should use java.lang.ThreadLocal
With Java 8 we can achieve lazy initialization with thread safety. If we have Holder class and it needs some heavy resources then we can lazy load the heavy resource like this.
public class Holder {
private Supplier<Heavy> heavy = () -> createAndCacheHeavy();
private synchronized Heavy createAndCacheHeavy() {
class HeavyFactory implements Supplier<Heavy> {
private final Heavy heavyInstance = new Heavy();
#Override
public Heavy get() {
return heavyInstance;
}
}
if (!HeavyFactory.class.isInstance(heavy)) {
heavy = new HeavyFactory();
}
return heavy.get();
}
public Heavy getHeavy() {
return heavy.get();
}
}
public class Heavy {
public Heavy() {
System.out.println("creating heavy");
}
}
Basing this answer on #Alexsalauyou's one I thought if it could be possible to implement a solution that does not call multiple instances.
In principle my solution may be a little bit slower (very very little), but it is definitely friendlier to the processor, and the garbage collector.
The idea is that you must first use a container which could hold an "int" value PLUS the generic you want to instance.
static class Container<T> {
final int i;
final T val;
//constructor here
}
Let this container's fields be final for concurrency purposes.
The LazyInit<T> class, must have an AtomicReference of this container.
AtomicReference<Container<T>> ref;
LazyInit must define phase processes as private static int constants:
private static final int NULL_PHASE = -1, CREATING_PHASE = 0, CREATED = 1;
private final Container<T> NULL = new Container<>(NULL_PHASE, null),
CREATING = new Container<>(CREATING_PHASE, null);
NULL and CREATING containers can be made static and upgraded to <?> to make things lighter, then one could grab them with a casting private static method.
The AtomicReference must be initialized as NULL:
private final AtomicReference<Container<T>> ref = new AtomicReference<>(getNull());
Finally the get() method would look like this:
#Override
public T get() {
Container<T> prev;
while ((prev = ref.get()).i < CREATED) {
if (ref.compareAndSet(getNull(), getCreating())) {
T res = builder.get();
ref.set(new Container<>(CREATED, res));
return res;
}
}
return prev.value;
}
Try to defined the method which gets an instance as synchronized:
public synchronized Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
Or use a variable:
private static final String LOCK = "LOCK";
public synchronized Foo getInstance(){
synchronized(LOCK){
if(INSTANCE == null){
INSTANCE = new Foo();
}
}
return INSTANCE;
}
Related
This is a contrived code example but based on a real world testing scenario from an Android project. It involves using class constructors to determine the validity of the class (ensure its in the correct state to be used). In this case just checking that the class constructor does not throw an exception before returning an instance of the class:
public class MyTestClass {
private MyTestClass() {
// Some code which might throw an exception
}
public static MyTestClass getInstance() {
if (tryClassConstructor(MyTestClass::new)) {
return new MyTestClass();
}
return null;
}
private static boolean tryClassConstructor(Runnable condition) {
try {
condition.run();
} catch (ArithmeticException ex) {
return false;
}
return true;
}
}
I understand that getInstance() is passing a constructor method reference (MyTestClass::new) to its tryClassConstructor() method, but that method expects... a Runnable. So does this mean class default constructors are by default Runnable?
You can do the following in a Runnable:
Runnable r = () -> {
new MyTestClass();
};
Note that isn't returning the instance of MyTestClass: it's simply invoking the constructor, and discarding the instance.
That's all MyTestClass::new does when you use it as a Runnable.
You can do this because MyTestClass::new is void-compatible. new MyTestClass() is a statement expression, so it can stand by itself as a statement.
In your example, the ´Runnable´ is equivalent to
Runnable r = () -> new MyTestClass();
You can refer to this article for more information ("Reference to a Constructor").
Suppose I declare like this:
private static Boolean isCondition = false;
Then I am using this like below in synchronized statement:
synchronized(isCondition){
isCondition = true;
somestuff();
}
Here my question is if I update isCondition then it will get a new reference due to autoboxing and if new thread will come in synchronized block then they will get lock on new object enter into synchronized block. This I dont want to happen.
So please suggest me alternatives and if I use volatile then how exactly it will prevent this like below:
private static volatile Boolean isCondition = false;
The actual code is like that:
package com.test.spring.utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* #author Pratik
*/
public class TouchPointsSpringContext implements ApplicationContextAware
{
private static final Log g_log = LogFactory.getLog(TouchPointsSpringContext.class);
private static ApplicationContext CONTEXT;
private static volatile Boolean isServiceInitialized = false;
/**
* This method is called from within the ApplicationContext once it is done
* starting up, it will stick a reference to itself into this bean.
*
* #param context
* a reference to the ApplicationContext.
*/
public void setApplicationContext(ApplicationContext context) throws BeansException
{
CONTEXT = context;
}
private static void initializeTouchPointService()
{
g_log.info("getting touchpoints service application context");
String[] locations =
{ "appContext-main.xml", "appContext-hibernate.xml" };
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(locations);
g_log.info("setting touchpoints service application context");
CONTEXT = applicationContext;
}
/**
* This is about the same as context.getBean("beanName"), except it has its
* own static handle to the Spring context, so calling this method
* statically will give access to the beans by name in the Spring
* application context. As in the context.getBean("beanName") call, the
* caller must cast to the appropriate target class. If the bean does not
* exist, then a Runtime error will be thrown.
*
* #param beanName
* the name of the bean to get.
* #return an Object reference to the named bean.
*/
public static Object getBean(String beanName)
{
if (!isServiceInitialized || (CONTEXT == null))
{
synchronized (isServiceInitialized)
{
if (!isServiceInitialized)
{
initializeTouchPointService();
isServiceInitialized = true;
}
}
}
return CONTEXT.getBean(beanName);
}
public static void main(String[] args)
{
TouchPointsSpringContext.getBean("lookupService");
}
}
Using a Boolean as a lock is a very bad idea: you are effectively using a global variable Boolean.TRUE/FALSE which any other parts of your code can access and potentially deadlock your code.
And using a non final variable as a lock is an even worse idea: everytime you reallocate the instance (isCondition = true) you change your lock, meaning that two threads may execute your synchronized block concurrently, which kind of defeats the whole idea.
So I would recommend a standard idiom:
private static final Object lock = new Object();
private static boolean isCondition;
synchronised(lock) {
isCondition = true;
// ...
}
I think most of the other answers here are not completely right. It is a little bit difficult to understand what you are doing because you do not include the code for initializeTouchPointService, however you appear to be doing something which is a variation on the "Double Checked Locking" idiom.
It is difficult to get this concurrency idiom right and if you are using a version of Java before 5, then you should not attempt to use this idiom at all. I will assume you are using Java 5+.
The important parts of your code are:
private static ApplicationContext CONTEXT;
private static volatile Boolean isServiceInitialized = false;
...
if (!isServiceInitialized || (CONTEXT == null))
{
synchronized (isServiceInitialized)
{
if (!isServiceInitialized)
{
initializeTouchPointService();
isServiceInitialized = true;
}
}
}
Assuming that you are using Java 5 or above, you must use volatile on all relevant variables to get this idiom to work correctly. You must also re-check the full condition inside the synchronized block.
You must not use a Boolean as your lock, since Boolean objects are immutable you will get a different object when you change the condition from false to true. Instead use a separate lock object and boolean primitive for the condition.
private final Object lock = new Object();
private volatile boolean isServiceInitialized;
private volatile ApplicationContext context;
public Object getBean(String beanName) {
if (!isServiceInitialized || context == null) {
synchronized(lock) {
if (!isServiceInitialized || context == null) {
initializeTouchPointService();
isServiceInitialized = true;
}
}
}
return CONTEXT.getBean(beanName);
}
However, locks in recent versions of Java have very good performance on most architectures. So using the double-checked locking idiom may not make your program much faster - especially compared to how slow spring reflection will be when calling getBean.
Instead of your double-checked design, how about the following simpler design which also avoids volatile:
private final Object lock = new Object();
private boolean isServiceInitialized;
private ApplicationContext context;
private ApplicationContext context() {
synchronized(lock) {
if (!isServiceInitialized || context == null) {
initializeTouchPointService();
condition = true;
}
return context;
}
}
public Object getBean(String beanName) {
return context().getBean(beanName);
}
I also recommend avoiding the use of static where ever possible, as writing unit tests in the presence of global variables can be tricky. I would seriously consider if there is any way you can change your design to reduce or eliminate your use of static state.
============ edit
Based on my best guess of what the OP is trying to achieve, perhaps this would be better. However, it removes the lazy initialisation. So if you program sometimes refers to this TouchPointsSpringContext class without using the getBean() method then you don't want this answer.
public class TouchPointsSpringContext
{
private static final Log g_log = LogFactory.getLog(TouchPointsSpringContext.class);
private static ApplicationContext CONTEXT = initializeTouchPointService();
private static ApplicationContext initializeTouchPointService()
{
g_log.info("getting touchpoints service application context");
String[] locations =
{ "appContext-main.xml", "appContext-hibernate.xml" };
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(locations);
g_log.info("setting touchpoints service application context");
return applicationContext;
}
public static Object getBean(String beanName)
{
return CONTEXT.getBean(beanName);
}
public static void main(String[] args)
{
TouchPointsSpringContext.getBean("lookupService");
}
}
Note that the JVM will automatically make sure that your static CONTEXT gets initalised exactly once.
Or alternatively, if you can avoid implementing "ApplicationContextAware" (implementing it seems unnecessary given the rest of the code), but you need to keep he lazy initialisation, then this might be better:
public class TouchPointsSpringContext
{
private static final Log g_log = LogFactory.getLog(TouchPointsSpringContext.class);
private static volatile ApplicationContext CONTEXT;
private static final Object lock = new Object();
private static ApplicationContext initializeTouchPointService()
{
g_log.info("getting touchpoints service application context");
String[] locations =
{ "appContext-main.xml", "appContext-hibernate.xml" };
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(locations);
g_log.info("setting touchpoints service application context");
return applicationContext;
}
public static Object getBean(String beanName)
{
if (CONTEXT == null)
{
synchronized (lock)
{
if (CONTEXT == null)
{
CONTEXT = initializeTouchPointService();
}
}
}
return CONTEXT.getBean(beanName);
}
public static void main(String[] args)
{
TouchPointsSpringContext.getBean("lookupService");
}
}
Not a full answer, but: Several people here said things like "You must not use Boolean as a lock because..."
Those explanations complicate what should be a simple idea. When you write synchronized (foo) { ... }, you are not synchronizing on the variable foo, you are synchronizing on some object that is the result of the expression, foo.
You did something like this in your example:
Boolean isCondition = ...;
synchronized(isCondition) {
isCondition = true;
...
}
When a thread enters that synchronized block, it acquires the monitor for a particular instance of the Boolean class. Then, the next thing that it does is assign isCondition. The same variable now points to a different instance.
When a second thread tries to enter the same block, it will attempt to synchronize on the new instance, and it will succeed even if the first thread still is in the block. The only thing that synchronized prevents is, it prevents two different threads from synchronizing on the same instance at the same time. In your example, the two different threads synchronized on two different instances, and that is allowed.
Never do this:
synchronized ( foo ) {
...
foo = ...;
...
}
A good practice is, if you are going to put a simple variable name in the parens (and that's by far the most common use-case), then make it a final variable.
final MyThingummie myThingummie = new MyThingummie(...);
synchronized ( myThingummie ) {
...
}
As some others have suggested in comments, you could synchronize on something else and avoid this problem.
Define a new variable to lock on:
private final Object lock;
Now change your code a bit:
synchronized(lock) {
isCondition = true;
somestuff();
}
You can also achieve similar functionality without the variable by having all of this in a synchronized method.
I work on a game-like system. Users can submit .class and .java files for customized behaviour. Some objects are delivered to the user via callback, but if the user can construct these object himself (with custom parameters), it would mean an advantage to him. I will disallow reflection for the user and seal my packages. I can get this working if I abandon all package structure (and make the constructors package-private), but I would like not to do so.
Here is an example:
sscce.mycode.a.SomeClass.java:
package sscce.mycode.a;
import sscce.mycode.b.RestrictedObject;
import sscce.usercode.SomeUserClass;
public class SomeClass {
public static void main(String[] args) {
SomeUserClass userClass=new SomeUserClass();
// If I can create it from here, anyone can...
RestrictedObject object=new RestrictedObject();
userClass.someMethod(object);
}
}
sscce.mycode.b.Interface.java:
package sscce.mycode.b;
public interface Interface {
public void someMethod(RestrictedObject restrictedObject);
}
sscce.mycode.b.RestrictedObject.java:
package sscce.mycode.b;
public class RestrictedObject {
public RestrictedObject() {}
}
sscce.usercode.SomeUserClass.java:
package sscce.usercode;
import sscce.mycode.b.Interface;
import sscce.mycode.b.RestrictedObject;
public class SomeUserClass implements Interface {
#Override
public void someMethod(RestrictedObject restrictedObject) {
// It receives an instance, but cannot create it.
System.out.println("Got "+restrictedObject);
}
}
Motivation: Having everything in one package sounds messy...
Does anyone have ideas on how to accomplish this without flattening the packages?
Thanks in advance for any solutions, ideas or comments, Till
You could do it the following way, however you should carefully consider if you really want to use this approach as it is very slow and quite frankly, bad practice.
I'll put it up anyway as to how you can do it:
public final class Secured {
private static final Set<Class<?>> allowedCallers = new HashSet<>();
static {
allowedCallers.add(Allowed.class);
}
private static final class SecurityManagerExtension extends SecurityManager {
private static final int OFFSET = 4;
#Override
protected Class<?>[] getClassContext() {
return super.getClassContext();
}
private Class<?> getCaller() {
try {
return getClassContext()[OFFSET];
} catch (ArrayIndexOutOfBoundsException e) {
return null;
}
}
}
private Secured() {
// protect against reflection attack
Class<?> caller = new SecurityManagerExtension().getCaller();
if (!this.getClass().equals(caller)) {
throw new IllegalStateException();
}
System.out.println("Secured instance constructed!");
}
public static Secured createInstance() {
// this gets the class name of the calling class
Class<?> caller = new SecurityManagerExtension().getCaller();
if (allowedCallers.contains(caller)) {
System.out.println("Created instance by '" + caller + "'!");
return new Secured();
} else {
System.out.println("No instance created because call was made by '" + caller + "'!");
return null;
}
}
}
Note the final keyword on the class to prevent subclassing. If you need to subclass the class yourself, move the final keyword to the factory method.
Also note that this is not protected against serialization attacks.
What is the preferred way to work with Singleton class in multithreaded environment?
Suppose if I have 3 threads, and all of them try to access getInstance() method of singleton class at the same time -
What would happen if no synchronization is maintained?
Is it good practice to use synchronized getInstance() method or use synchronized block inside getInstance().
Please advise if there is any other way out.
If you're talking about threadsafe, lazy initialization of the singleton, here is a cool code pattern to use that accomplishes 100% threadsafe lazy initialization without any synchronization code:
public class MySingleton {
private static class MyWrapper {
static MySingleton INSTANCE = new MySingleton();
}
private MySingleton () {}
public static MySingleton getInstance() {
return MyWrapper.INSTANCE;
}
}
This will instantiate the singleton only when getInstance() is called, and it's 100% threadsafe! It's a classic.
It works because the class loader has its own synchronization for handling static initialization of classes: You are guaranteed that all static initialization has completed before the class is used, and in this code the class is only used within the getInstance() method, so that's when the class loaded loads the inner class.
As an aside, I look forward to the day when a #Singleton annotation exists that handles such issues.
Edited:
A particular disbeliever has claimed that the wrapper class "does nothing". Here is proof that it does matter, albeit under special circumstances.
The basic difference is that with the wrapper class version, the singleton instance is created when the wrapper class is loaded, which when the first call the getInstance() is made, but with the non-wrapped version - ie a simple static initialization - the instance is created when the main class is loaded.
If you have only simple invocation of the getInstance() method, then there is almost no difference - the difference would be that all other sttic initialization would have completed before the instance is created when using the wrapped version, but this is easily dealt with by simply having the static instance variable listed last in the source.
However, if you are loading the class by name, the story is quite different. Invoking Class.forName(className) on a class cuasing static initialization to occur, so if the singleton class to be used is a property of your server, with the simple version the static instance will be created when Class.forName() is called, not when getInstance() is called. I admit this is a little contrived, as you need to use reflection to get the instance, but nevertheless here's some complete working code that demonstrates my contention (each of the following classes is a top-level class):
public abstract class BaseSingleton {
private long createdAt = System.currentTimeMillis();
public String toString() {
return getClass().getSimpleName() + " was created " + (System.currentTimeMillis() - createdAt) + " ms ago";
}
}
public class EagerSingleton extends BaseSingleton {
private static final EagerSingleton INSTANCE = new EagerSingleton();
public static EagerSingleton getInstance() {
return INSTANCE;
}
}
public class LazySingleton extends BaseSingleton {
private static class Loader {
static final LazySingleton INSTANCE = new LazySingleton();
}
public static LazySingleton getInstance() {
return Loader.INSTANCE;
}
}
And the main:
public static void main(String[] args) throws Exception {
// Load the class - assume the name comes from a system property etc
Class<? extends BaseSingleton> lazyClazz = (Class<? extends BaseSingleton>) Class.forName("com.mypackage.LazySingleton");
Class<? extends BaseSingleton> eagerClazz = (Class<? extends BaseSingleton>) Class.forName("com.mypackage.EagerSingleton");
Thread.sleep(1000); // Introduce some delay between loading class and calling getInstance()
// Invoke the getInstace method on the class
BaseSingleton lazySingleton = (BaseSingleton) lazyClazz.getMethod("getInstance").invoke(lazyClazz);
BaseSingleton eagerSingleton = (BaseSingleton) eagerClazz.getMethod("getInstance").invoke(eagerClazz);
System.out.println(lazySingleton);
System.out.println(eagerSingleton);
}
Output:
LazySingleton was created 0 ms ago
EagerSingleton was created 1001 ms ago
As you can see, the non-wrapped, simple implementation is created when Class.forName() is called, which may be before the static initialization is ready to be executed.
The task is non-trivial in theory, given that you want to make it truly thread safe.
A very nice paper on the matter is found # IBM
Just getting the singleton does not need any sync, since it's just a read. So, just synchronize the setting of the Sync would do. Unless two treads try to create the singleton at start up at the same time, then you need to make sure check if the instance is set twice (one outside and one inside the sync) to avoid resetting the instance in a worst case scenario.
Then you might need to take into account how JIT (Just-in-time) compilers handle out-of-order writes. This code will be somewhat near the solution, although won't be 100% thread safe anyway:
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
Singleton inst = instance;
if (inst == null) {
synchronized(Singleton.class) {
instance = new Singleton();
}
}
}
}
return instance;
}
So, you should perhaps resort to something less lazy:
class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
Or, a bit more bloated, but a more flexible way is to avoid using static singletons and use an injection framework such as Spring to manage instantiation of "singleton-ish" objects (and you can configure lazy initialization).
You need synchronization inside getInstance only if you initialize your singleton lazily. If you could create an instance before the threads are started, you can drop synchronization in the getter, because the reference becomes immutable. Of course if the singleton object itself is mutable, you would need to synchronize its methods which access information that can be changed concurrently.
This question really depends on how and when your instance is created. If your getInstance method lazily initializes:
if(instance == null){
instance = new Instance();
}
return instance
Then you must synchronize or you could end up with multiple instances. This problem is usually treated in talks on Double Checked Locking.
Otherwise if you create a static instance up front
private static Instance INSTANCE = new Instance();
then no synchronization of the getInstance() method is necessary.
The best way as described in effective java is:
public class Singelton {
private static final Singelton singleObject = new Singelton();
public Singelton getInstance(){
return singleObject;
}
}
No need of synchronization.
Nobody uses Enums as suggested in Effective Java?
If you are sure that your java runtime is using the new JMM (Java memory model, probably newer than 5.0), double check lock is just fine, but add a volatile in front of instance. Otherwise, you'd better use static internal class as Bohemian said, or Enum in 'Effective Java' as Florian Salihovic said.
For simplicity, I think using enum class is a better way. We don't need to do any synchronization. Java by construct, always ensure that there is only one constant created, no matter how many threads are trying to access it.
FYI, In some case you need to swap out singleton with other implementation. Then we need to modify class, which is violation of Open Close principal.Problem with singleton is, you can't extend the class because of having private constructor. So, it's a better practice that client is talking via interface.
Implementation of Singleton with enum class and Interface:
Client.java
public class Client{
public static void main(String args[]){
SingletonIface instance = EnumSingleton.INSTANCE;
instance.operationOnInstance("1");
}
}
SingletonIface.java
public interface SingletonIface {
public void operationOnInstance(String newState);
}
EnumSingleton.java
public enum EnumSingleton implements SingletonIface{
INSTANCE;
#Override
public void operationOnInstance(String newState) {
System.out.println("I am Enum based Singleton");
}
}
The Answer is already accepted here, But i would like to share the test to answer your 1st question.
What would happen if no synchronization is maintained?
Here is the SingletonTest class which will be completely disaster when you run in multi Threaded Environment.
/**
* #author MILAN
*/
public class SingletonTest
{
private static final int PROCESSOR_COUNT = Runtime.getRuntime().availableProcessors();
private static final Thread[] THREADS = new Thread[PROCESSOR_COUNT];
private static int instancesCount = 0;
private static SingletonTest instance = null;
/**
* private constructor to prevent Creation of Object from Outside of the
* This class.
*/
private SingletonTest()
{
}
/**
* return the instance only if it does not exist
*/
public static SingletonTest getInstance()
{
if (instance == null)
{
instancesCount++;
instance = new SingletonTest();
}
return instance;
}
/**
* reset instancesCount and instance.
*/
private static void reset()
{
instancesCount = 0;
instance = null;
}
/**
* validate system to run the test
*/
private static void validate()
{
if (SingletonTest.PROCESSOR_COUNT < 2)
{
System.out.print("PROCESSOR_COUNT Must be >= 2 to Run the test.");
System.exit(0);
}
}
public static void main(String... args)
{
validate();
System.out.printf("Summary :: PROCESSOR_COUNT %s, Running Test with %s of Threads. %n", PROCESSOR_COUNT, PROCESSOR_COUNT);
long currentMili = System.currentTimeMillis();
int testCount = 0;
do
{
reset();
for (int i = 0; i < PROCESSOR_COUNT; i++)
THREADS[i] = new Thread(SingletonTest::getInstance);
for (int i = 0; i < PROCESSOR_COUNT; i++)
THREADS[i].start();
for (int i = 0; i < PROCESSOR_COUNT; i++)
try
{
THREADS[i].join();
}
catch (InterruptedException e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
testCount++;
}
while (instancesCount <= 1 && testCount < Integer.MAX_VALUE);
System.out.printf("Singleton Pattern is broken after %d try. %nNumber of instances count is %d. %nTest duration %dms", testCount, instancesCount, System.currentTimeMillis() - currentMili);
}
}
Output of the program is clearly shows that you need handle this using getInstance as synchronized or add synchronized lock enclosing new SingletonTest.
Summary :: PROCESSOR_COUNT 32, Running Test with 32 of Threads.
Singleton Pattern is broken after 133 try.
Number of instance count is 30.
Test duration 500ms
In my work I stumbled upon such a design issue:
I need one instance of a Manager class per thread
These instances should be globally accessible, like in the singleton pattern via a static function
Each thread might need to initialize its instance with different arguments
The lifetime of these instances should be controllable, sometimes it would be beneficiary to remove an instance and allow GC to collect it
The first two points would make it a 'per thread singleton' if such a thing exists.
This is what I came up with (the code is simplified, I've omitted safety checks and so on):
public class Manager {
private final static ThreadLocal<Manager> local = new ThreadLocal<Manager>();
private int x;
Manager(int argument) { x = argument; }
public static void start(int argument) { local.set(new Manager(argument); }
public static void clean() { local.remove(); }
private void doSomething1() { x++; .... }
private int doSomething2() { if (--x == 0) clean(); ... }
public static void function1() { local.get().doSomething1(); }
public static int function2() { return local.get().doSomething2(); }
}
As you can see the clean function can be also called from within the private methods.
Also notice that through the use of static functions the reference to the instance is never leaked, so instances assigned to different threads won't get mixed.
This works quite ok, but then I got another requirement:
Different threads may need to utilize different implementations of Manager class
So I defined an interface:
public interface ManagerHandler {
void method1();
int method2();
}
And modified the Manager class:
public class Manager {
private final static ThreadLocal<ManagerHandler> local = new ThreadLocal<ManagerHandler>();
public static void start(int argument) {
ManagerHandler handler;
// depending on the context initialize handler to whatever class it is necessary
local.set(handler);
}
public static void clean() { local.remove(); }
public static void function1() { local.get().method1(); }
public static int function2() { return local.get().method2(); }
}
An example implementation would look like this:
public class ExampleManagerImplementation implements ManagerHandler {
private int x;
public ExampleManagerImplementation(int argument) { x = argument; }
public void method1() { x++; .... }
public int method2() { if (--x == 0) Manager.clean(); ... }
}
Manager class works here as a facade, forwarding all the calls to the appropriate handler. There is one big issue with this approach: I need to define all the functions both in the Manager class and in the ManagerHandler interface. Unfurtunately Manager class can't implement ManagerHandler interface, because it has static functions rather than methods.
The question is: can you think of a better/easier way to accomplish all the goals I've listed above that would be free of this issue?
There is not much you can do, as you basically need to proxy interface methods through static methods. I could only think of two ways to achieve the same functionality differently:
If you're using a DI framework, you can get rid of the static Manager and use an injected implementation of ManagerHandler which will contain the ThreadLocal.
Generate (as in 'bytecode generation') the static ManagerAccess class using the methods found in the ManagerHandler interface.
Personally, I wouldn't think of having the static ManagerAccess class (which contains the ThreadLocal) around as a serious design issue. At least as long as it keeps to its own set of responsibilities (accessing thread-scoped instances and proxying calls) and doesn't venture anywhere else.
If you're going with this design, is it necessary for Manager to totally hide ManagerHandler interface, or could you expose it so you don't have to delegate every method?
class Manager {
public static ManagerHandler getHandler() { return local.get(); }
}
The trick for creating a singleton per thread class is to use ThreadStatic attribute on your private static _current field which makes it scoped by thread. In this way, the _current field will be stored inside thread memory which is not accessible for the other threads and not shared memory of AppDomain. So, it will be available only in the scope of the thread. On the other hand, the Current property is accessible across all threads in that AppDomain but when it is called it will return the correct instance for that thread. Here is the code that you need:
public sealed class Manager
{
// As you are using the ThreadStatic here you cannot
// call the static constructor or use the Lazy implimentation for
// thread-safty and you have to use the old fashin Lock and anti-pattern.
private static readonly object _criticalArea = new object();
[ThreadStatic]
private static Manager _current;
public static Manager Current
{
get
{
if (_current == null)
{
lock (_criticalArea)
{
if (_current == null)
{
_current = new Manager();
}
}
}
return _current;
}
}
private Manager()
{
}
public string WhatThreadIsThis { get; set; }
}
[TestClass]
public class SingeltonPerThreadTest
{
private readonly EventWaitHandle _threadHandler = new EventWaitHandle(false, EventResetMode.AutoReset);
private string _sharedMemory = "I am the shared memory and yet in main thread :(";
[TestMethod]
public void TestSingeltonPerThread()
{
// Creates a _current for main thread.
Manager.Current.WhatThreadIsThis = "I am the main thread :)";
// Start another thread.
(new Thread(CallTheThreadBaseSingelton)).Start();
// Wait for it to be finished.
_threadHandler.WaitOne();
Assert.AreEqual("I am the main thread :)", Manager.Current.WhatThreadIsThis, "I am not the main thread :( ");
Assert.AreEqual("I am the other thread ;)", _sharedMemory, _sharedMemory);
}
private void CallTheThreadBaseSingelton()
{
// Creates a _current for this thread (this thread is the other one :)) ).
Manager.Current.WhatThreadIsThis = "I am the other thread ;)";
_sharedMemory = Manager.Current.WhatThreadIsThis;
_threadHandler.Set();
}
}
Cheers.