Consider the following scenario:
You have a singleton class that represent some sort of data provider.
This singleton class allocates a lot of memory,and you want it to release it's allocated memory when there is no one using him.
Flow:
Class A call getInstance and uses singleton (this is the first time getInstance called and singleton class allocates huge memory chunk)
Class B call getInstance and uses singleton
Class A and class B "dies" (no one using singleton now)
Program still running but singleton's memory is not released.
How do you suggest implementing singleton that at stage 3 (class A and B "dies") will free the memory (I know that java uses garbage collection but still lets say I want the following memory = null).
PS
I don't want to force each class that uses the singleton call release on singleton whenever it stops using it. I want the singleton to handle "releasing" memory by himself.
What you can do is
only create the singleton the first time it is asked for.
store it in a WeakReference. This will only stay alive after a GC if it is still has a "strong" reference elsewhere.
If the WeakReference.get() is null this means it was collected because no-one was using it strongly, another weak reference doesn't count. If it is needed again you need to recreate it and the WeakReference.
Like this,
public enum SingletonHolder{; // no instances
private static WeakReference<MyType> ref = null;
public static synchronized MyType getInstance() {
MyType type = ref == null ? null : ref.get();
if (type == null)
ref = new WeakReference<MyType>(type = new MyType());
return type;
}
}
BTW This assumes the instances which need this instance retains a reference to it. This is how the weak reference "knows" it is still needed.
BTW2 You don't need synchronized if it is single threaded but it should be harmless.
This means that you should call this method only when a new instance needs it for the first time, not every time and making it more performant shouldn't make much difference e.g. double checking just complicates it.
The use of the Design pattern: "Singleton" is very common and the common implementation is using a static reference.
The problem with this implementation is that many times it leaves floating garbage that is not in use.
For example:
A singleton that holds a DB connection pool that is only needed by the application at the start up for confing loading.
Therefor a better solution is an extension to the Singleton design pattern called WeakSingleton.
This pattern does the expected, when all other references to the original instance have expired the instance is cleaned.
An implemenation to this pattern in java is very simple and can be based on WeakReferences.
E.g. Code:
public class WeakSingleton{
static private WeakReference singleton; // instance
public WeakSingleton getInstance(){
WeakSingleton m = (WeakSingleton)singleton.get();
if( m != null)
return m;
synchronized (WeakSingleton.class){
m = (WeakSingleton)singleton.get();
if( m != null)
return m;
m = new WeakSingleton(); // creates new instnace
singleton = new WeakReference(m);
}
return m;
}
}
Related
I want to have a resettable object instance for a session within my program that is thread safe, an example of a session might be a logged in user session.
I am currently doing something like this;
public final class ObjectFactory {
private static volatile NativeObjectWrapper instance = null;
private Singleton() {}
public static NativeObjectWrapper getInstance() {
if (instance == null) {
synchronized(ObjectFactory.class) {
if (instance == null) {
instance = new NativeObjectWrapper(AuthData);
}
}
}
return instance;
}
public void reset() {
synchronized(ObjectFactory.class) {
instance = null;
}
}
}
I want to have the object created lazily, with the ability to reset it. Is the above approach threadsafe? if not is there a common pattern to solve this?
An example again would be that scoped object here has some inner data based on the user session and therefore should be a new instance per user session.
Is the above approach threadsafe?
No, it is not.
Say we have two threads - A and B.
A calls getInstance(), passes the instance==null check, and then there's a context switch to B, which calls reset(). After B finishes executing reset(), A gets the context again and returns instance, which is now null.
if not is there a common pattern to solve this?
I don't remember seening singletons with a reset method, so I'm not aware of any common patterns for this problem. However, the simplest solution would be to just remove the first if (instance == null) check in getInstance(). This would make your implementation thread safe, as instance is always checked and modified within a synchronized block. In this scenario, you could also remove the volatile modifier from instance since it is always accessed from within a synchronized block.
There are more complex solutions I can think of, but I'd use them only if real-world profiling showed that you're spending too much time blocked on that synchronized block. Note that the JVM has some sophisticated ways of avoiding using "real" locks to minimize blocking.
One trickier approach could be to read the instance field just once:
public static Singleton getInstance() {
Singleton toReturn = instance;
if (toReturn == null) {
synchronized(SingletonFactory.class) {
if (instance == null) {
instance = new Singleton();
toReturn = instance;
}
}
}
return toReturn ;
}
But this could result in returning an old "instance". For example a thread could execute Singleton toReturn = instance and get a valid instance, then lose the CPU. At this point, a 1000 other threads could create and reset 1000 other instances until the original thread gets a spin on the CPU again, at which point it returns an old instance value. It's up to you whether such a case is acceptable.
Is the above approach threadsafe?
The answer depends on what you think "thread safe" means. There is nothing in your reset() method to prevent a thread that previously called getInstance() from continuing to use the old instance.
Is that "thread safe?"
Generally speaking, "thread safe" means that the actions of one thread can never cause other threads to see shared data in an inconsistent or invalid state. But what "inconsistent" or "invalid" mean depends on the structure of the shared data (i.e., on the design of the application.)
Another way of looking at it: If somebody tells you that a class is "thread safe," then they're probably telling you that concurrent calls to the class's methods by multiple threads will not do anything that disagrees with the class documentation and, will not do anything that disagrees with how a reaonable programmer thinks the class should behave in cases where the documentation is not absolutely clear.
NOTE: That is a weaker definition of "thread safety" because it glosses over the fact that, using thread-safe components to build a system does not guarantee that the system itself will be thread-safe.
Does everybody who uses your class clearly understand that no thread in the program may ever call reset() while any reference to the old singleton still exists? If so, then I would call that a weak design because it is very far from being "junior-programmer-safe," but I would grudgingly admit that, from a strict, language-lawyerly point of view, you could call your ObjectFactory class "thread safe."
Is there any functional difference between these two ways of implementing a Singleton?
public class MySingleton {
private static MySingleton instance;
public static MySingleton getInstance() {
if (instance == null) {
instance = new MySingleton();
}
return instance;
}
}
public class MySingleton {
private static final MySingleton instance = new MySingleton();
public static MySingleton getInstance() {
return instance;
}
}
Besides the fact that the first way would allow for some sort of clearInstance() method. Though you could just make instance not final in the second method.
Does the first method technically perform better because it is only initialized the first time it is needed instead of when the program starts?
The first one is lazy loading and the second is eager loading. Maybe your application never call the singleton, so if creating new instance of your singleton be heavy resource consuming action, then the lazy loading is better since it create new instance once needed.
The first method you use is not thread safe. I would consider it to be a bug.
The second method is simpler, thread safe, fast and, if you make sure the constructor won't throw silly exceptions, correct.
If you absolutely need more logic you can go with the first method, must make sure you protect it with a mutex. Something like:
public class MySingleton {
private static final Object mylock = new Object();
private static MySingleton instance;
public static MySingleton getInstance() {
synchronized(mylock) {
if (instance == null) {
instance = new MySingleton();
}
return instance;
}
}
}
Clearly the code is more complex, uses more memory, it's slower, you can't declare the variable as final...
Both methods will initialize the Singleton lazily. In Java, all variable initialization and static constructors are involved by the class loader when the class is used, not on the start of the code. If your code path never invokes getInstance the Singleton will never get initialized.
Personally, I avoid singletons, but when I use them is always with an immediate allocation on the variable declaration.
Correction
I ran a few experiments, and it turns out class initialization happened in parallel with the execution of the main thread. It didn't waited, as I believed it would. At least on a very simplified test scenario the initialization is eager, but asynchronous.
Is there any functional difference between these two ways of implementing a Singleton?
Yes. If you use an initializer in the variable declaration, then the instance is created when the class is initialized, even if the instance is never accessed. If you initialize it in the getInstance() method then the instance is only created if it is accessed. That has thread safety implications. It does does not otherwise make much difference if initializing an instance is cheap and without lasting external side effects, but that may not always be the case.
Does the first method technically perform better because it is only
initialized the first time it is needed instead of when the program
starts?
If you are going to use an instance in any case then you are going to pay the cost of initializing it at some point no matter what, so there is no performance difference in that sense. However, a thread-safe version of the first method will be slightly more expensive than the second method on the first invocation, and you will pay that extra overhead again on every subsequent invocation.
Its about Lazy Initialization vs Eager initialization. The difference is, in the first one the instance will not create until you call the getInstance() method, but in the second one its already have been created even before you call the getInstance() method.
Please refer this link if you want more info
From the unit testing point of view I prefer the lazy instatiatiation. Given that the singleton's initialization has further side effects (which are irrelevant to the actual test), and you want to test a class which needs the singleton (maybe just one particular method), it's easier to mock the singleton and inject it to the instance variable while preparing the test. Using a mock for your singleton instance you have easier control what the singleton's method return to your class under test.
The overhead of the thread safe instantiation can be minimized by the double checked lock pattern:
private static volatile MySingleton instance;
public static MySingleton getInstance() {
if (instance == null) {
synchronized ( MySingleton.class ) {
if (instance == null) {
instance = new MySingleton();
}
}
}
return instance;
}
Thus only the rare situation where two (or more) threads access the singleton for the first time (and at the same time) may enter the lock state. Afterwards the first ''if null'' will return false and you never enter the lock state again.
Important: the member has to be declared volatile for this pattern to work reliably.
Note: It has been proven that the above "double checked lock" pattern is not 100 percent reliable. See the discussion below in the comments and especially Brian Goetz' arcticle
I haven't understood what the code's purpose => DataProvider instance = sInstance; is in below method. Anyone help me to explain in detail ? Why don't use directly sInstance ?
private static volatile DataProvider sInstance = null;
public static DataProvider getInstance() {
DataProvider instance = sInstance;
if (instance == null) {
synchronized (DataProvider.class) {
instance = sInstance;
if (instance == null) {
instance = sInstance = new DataProvider();
}
}
}
return instance;
}
It is used as a lazy initialization (e.i. only create the singleton instance when needed). The problem with this code is that it is broken. Apparently even when using the synchronize block, there is a posaibility that things goes wrong (due to raceconditions). So do not use this method if you want to be safe!
Alternatives:
Using a direct assignment (like you sugessted);
private static volatile DataProvider sInstance = new DataProvider();
Or using a enum (as suggested by #MadProgrammer);
public enum DataProvider
{
INSTANCE;
// singleton content
}
According to the book Prentice.Hall.Effective.Java.2nd.Edition.May.2008 of Joshua Bloch,
In particular, the need for the local variable result may be unclear.
What this variable does is to ensure that field is read only once in
the common case where it’s already initialized. While not strictly
necessary, this may improve performance and is more elegant by the
standards applied to low-level concurrent programming. On my machine,
the method above is about 25 percent faster than the obvious version
without a local variable.
The main reason is Volatile. As #Hien Nguyen's answer, it improve 25% performance. Cause Volatile is always get data from main memory instead of cache, so it's too slow. Declare instance = sInstance to avoid read data from main memory multiple time (slow).
There're 3 time we read data from sInstance if we don't use temp variable, so we use temp variable will imporve performance.
See this topic to understand why access Volatile is slow: Why access volatile variable is about 100 slower than member?
Your answer maybe the same as this topic: Java: using a local variable in double check idiom
I am using a singleton created by the initialization-on-demand holder idiom.
When I´m done, I would like to "return" the singleton so that it can be used by other programs. Can I do this as follows...
Creating the Singleton
public class MyObject{
private MyObject(){}
private static class Holder{
private static final MyObject INSTANCE = new MyObject();
}
public static MyObject getInstance(){
return Holder.INSTANCE;
}
}
somewhere else I use this by
MyObject myObject = MyObject.getInstance();
// do something
myObject = null;
System.gc();
This accomplishes nothing:
myObject = null;
The singleton object will always be referenced by the final INSTANCE field in the Holder class, and it never will be GCd.
In fact, that's what "singleton" means. A "singleton" is a class for which only one instance is ever created, and the instance is never destroyed. If you want something else, then call it something else. Don't call it "singleton."
I bet you either want to use some form of mutual exclusion to prevent more than one thread from using the singleton at the same time, or else you want what #Newerth said: an object pool.
Also, this is obsolete: System.gc(); In the very early days of Java, it would bring everything else to a halt while the GC reclaimed all of the unused objects from the heap, but modern JVMs do continuous garbage collection in the background. The documentation for System.gc() has been changed to say that it's only a suggestion.
Yes that will work, but not sure why you need a holder class since your initialization is not costly (yet). If you are going to add more to the constructor later then fine, but otherwise it just clutters the code to have that other class.
There was a well-known pitfall while using the double-checked locking pattern (an example and explanation taken from "Concurrency in Practice"):
#NotThreadSafe
public class DoubleCheckedLocking {
private static Resource resource;
public static Resource getInstance() {
if (resource == null) {
synchronized (DoubleCheckedLocking.class) {
if (resource == null)
resource = new Resource();
}
}
return resource;
}
}
Some thread may see the initialized value of 'resource' variable, while the object itself is still under construction.
A question is: is the problem remains if we are constructing the resource object in some method? I.e.
resource = createResource();
Can some thread evaluate resource != null as true while the resource object is still under construction in createResource() method?
Yes, some thread can, or rather could. The code you posted works correctly these days. It was only with the earlier memory model (before Java 1.5) that the DCL pattern was flawed in.
Also DCL is obsolete these days since the best way to create a lazy loading singleton is with the singleton enum pattern.
To answer your question, in the example you gave, the behaviour would not change if you were using a method or calling new directly. What affects behaviour between threads is a memory barrier of some type. A method dispatch is not enough.
However, double checked locking works as of Java 5, although you need to use the volatile keyword on on the instance. (To provide the memory barrier, as it happens.)
Why is volatile used in this example of double checked locking