Lazy initialization in singleton looks useless - java

My question is that when we call getInstance() in singleton for the first time,then all its static properties are loaded in memory, i.e. before that it is not loaded in memory, so actually checking being null in the getInstance method is practically pointless and practically no different from the eager method, so why do we use this?
I also tried this by passing -verbose:class to the vm argument. At first, when I was not using any of these two classes, they were not in the list of loaded classes, and after calling getInstance, each of them was then loaded into memory.
terminal output:
[0.073s][info][class,load] patterns.singleton.Lazy source: file:/E:/design-pattern/out/production/design-pattern/
[0.073s][info][class,load] patterns.singleton.Eager source: file:/E:/design-pattern/out/production/design-patter
Update:Actually, my question is that there is no difference between lazy and eager. So what is the advantage of eager over lazy? I have nothing to do with whether it is thread safe or not, now my focus is on which one for this need: "When the client needs the object of this class, this object should be initialized, not from the beginning of the program." are better And I think that maybe they are not different
class Lazy{
private static Lazy lazy;
private Lazy(){}
public Lazy getInstance(){
if (lazy==null) // this two lines
lazy=new Lazy(); // are useless I think
return lazy;
}
}
//eager
class Eager{
private static Eager eager=new Eager(); //before calling the getInstance()
//the singleton is not initialized so inline initializing is not a problem
private Eager(){}
public Eager getInstance(){
return eager;
}
}

Related

What's the footprint of many instances built from a static method at runtime?

I've read articles talking about static class variables loading and static methods loading but very few about returned instantiated objects from static methods and their footprint.
Returning an instance from a static method is actually how singletons are created however singletons are supposed to be created once and then accessed by some getInstance method.
If I voluntarily want to break the singleton pattern, what happens if I write something like the following for example? (note the RandomSumBuilder build() method static access modifier)
public class Service {
public void doSomething() {
for (int i = 0; i < 1000; i++) {
System.out.println("Random sum : " + RandomSumBuilder.add().build());
}
}
}
public class RandomSumBuilder {
private List<Integer> aList = new ArrayList<>();
public RandomSumBuilder() { }
public static RandomSumBuilder add() {
RandomSumBuilder randomSumBuilder = new RandomSumBuilder();
randomSumBuilder.aList.add(new Random().nextInt(11));
return randomSumBuilder;
}
public int build() {
return aList.stream()
.reduce(Integer::sum)
.orElse(0);
}
}
To me it's clear RandomSumBuilder can't be considered as singletons but I can't get my head around these questions and I can only make assumptions so far.
Are the different RandomSumBuilder instances static?
(I'd say yes, like singletons)
Can these objects be elected for garbage collection?
(given my answer to question 1, I'd say no)
Does it put unnecessary work on the class loader?
(if it has to load that many RandomSumBuilder to instantiate these static objects, I'd say yes since I don't see the point in keeping them global. My quick local test with visualvm couldn't help me decide)
What would the builder pattern (with a nested class) bring here instead?
(I'd say way less static objects created and class loading work but being at my 4th consecutive assumption I'm not even sure)
I hope I'm not too lost in this subject, please correct me if I'm wrong.
Note that your example is not compilable and it is not possible to be sure about what the
Are the different RandomSumBuilder instances static?
That question is meaningless.
There is no such thing as a static instance. Seriously.
For example:
public class Test {
public static Test myTest = new Test();
}
The myTest variable is a static variable, but the instance that it points to is no different from any other instance of Test.
It is not a "static instance". There is no such thing.
The second issue is that your example is not creating any RandomSumBuilder instances at all.
Can these objects be elected1 for garbage collection?
Yes. Assuming that they are not assigned to something that makes it reachable.
Does it put unnecessary work on the class loader?
No. Unless you are creating multiple classloaders, the class only loaded once. The classloader doesn't get involved in creating instances.
What would the builder pattern (with a nested class) bring here instead?
How an object is created makes no difference to its reachability. It makes no difference that the method that creates it is static, or inner or nested.
On the other hand your code does this:
instanceB.aList.add(new Random().nextInt(11));
This doesn't compile because instanceB is not declared. But if instanceB was declared, and it was static, then that would be sufficient to make the Integer that you are (possibly) creating reachable.
But that is nothing to do with the build method being static ...
1 - English mistake: you are equating "candidates" with "election". Garbage collection is not democratic. And even in the real world, candidate has a broader meaning than that. Look it up in a dictionary ...

Is there a functional difference between initializing singleton in a getInstance() method, or in the instance variable definition

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

How to guarantee class loading

I have a class whose initialization takes quite a bit of time; it invokes a server and that server takes several minutes to become ready.
Methods on that class aren't called for quite a while and they are always called from a class that is automatically loaded on start-up. My set-up is like this:
class SlowToStartUp {
public static void init() {
// do nothing
}
static {
initiateConnectionToServer()
}
public static V invokeServer() {
waitForServerToConnect();
return valueFromServer();
}
}
class AlwaysLoaded {
static {
SlowToStartUp.init();
}
public void someMethod() {
V v = SlowToStartUp.invokeServer();
}
This strikes me as structurally correct. If there were no init() function at all, initiateConnectionToServer() wouldn't be called until someMethod() needed the class for the first time, and then there would be an unnecessary (and in my system, unacceptable) delay.
If I put the initiateConnectionToServer() call in init(), the interface would be more fragile (since the call might be forgotten).
But now I am wondering if I have outsmarted myself. The compiler can see that init() is empty. Could it not just optimize the call away? It does not do so now, but it that guaranteed?
I tried marking init() as volatile, but that is not allowed.
I am considering putting the actual initialization into init(), making sure it is idempotent, and invoking it from a static block, just to be on the safe side, but I thought I would ask for advice first.
One alternative approach would be to refactor to a singleton class instead of a bunch of static method. The singleton will then be created at startup and your initialization code would run right away.
public class SlowPokeSingleton {
private SlowPokeSingleton() { /* execute init code */ }
// created at startup
private final static SlowPokeSingleton instance = new SlowPokeSingleton();
public static SlowPokeSingleton instance() { return instance; }
}
You will need to call instance() to make sure the instance is actually created. You can add that to your server startup to be safe.
I have a tenuous answer to my own question. The events that trigger class initialization are specified in JLS 12.4.1.
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.
It seems to me that a compiler that optimized away an empty static function would violate the provision I marked in bold.
Comments welcome.
I agree with Giovanni Botta:
You could use a singleton pattern instead of static methods and fetch
the singleton instance as soon as your application starts. That would
force the JVM to create the instance and thus run your initialization
code. – Giovanni Botta
Specifically:
1) Put the "time consuming" part of your initialization into a private, static "init()" method.
2) Make your class's constructor "private".
3) Instead of a constructor, provide a public static "getInstance()" method to fetch a reference to your (already-initialized) singleton instance.
4) Your other methods can be non-static, if you wish.

Releasing instance of a singleton in java

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.

Java - Thread Synchronization in a web app

I have a web app where I load components lazily. There is a lot of
static Bla bla;
...
if(bla == null)
bla = new Bla();
spread throughout the code. What do I need to do to make sure this is thread safe? Should I just wrap anytime I do one of these initializations in a synchronized block? Is there any problem with doing that?
The best solution for lazy loading on a static field, as described in Effective Java [2nd edition, Item 71, p. 283] and Java Concurrency in Practice [p. 348], is the Initialization on demand holder idiom:
public class Something {
private Something() {
}
private static class LazyHolder {
private static final Something something = new Something();
}
public static Something getInstance() {
return LazyHolder.something;
}
}
It is tricky to use volatile variable.
It's described here:
http://www.ibm.com/developerworks/java/library/j-dcl.html
Example cited from above link:
class Singleton
{
private Vector v;
private boolean inUse;
private static Singleton instance = new Singleton();
private Singleton()
{
v = new Vector();
inUse = true;
//...
}
public static Singleton getInstance()
{
return instance;
}
}
will work 100% and is much more clear (to read and to understand) comparing to double checking and other approaches.
Assuming you are using Java 1.5 or later, you can do this:
private static volatile Helper helper = null;
public static Helper getHelper() {
if (helper == null) {
synchronized(Helper.class) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
That is guaranteed to be threadsafe.
I recommend you read this to understand why the var HAS to be volatile, and the double check for null is actually needed: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
The lazy instantiation is only really a part of the problem. What about accessing these fields?
Typically in a J2EE application you avoid doing this kind of thing as much as you can so that you can isolate your code from any threading issues.
Perhaps if you expand one what kind of global state you want to keep there are better ways to solve the problem.
That being said, to answer your question directly, you need to ensure that access to these fields is done synchronized, both reading and writing. Java 5 has better options than using synchronized in some cases. I suggest reading Java Concurrency in Practice to understand these issues.
The best way is indeed to enclose everything in a synchronized block, and declare the variable volatile, as in:
private static volatile Bla bla;
synchronized{
if(bla == null) bla = new Bla();
}
If you really need to have only one single instance assigned to the bla at any time you web application is running, you have to keep in mind the fact a static keyword applied to a variable declaration only ensures there will be one per classloader that reads the class definition of the class defining it.
Because bla is static, it can be accessed from different instances of the containing class
and code like
synchronized{...} or synchronized(this){...} does not defend against this. You must obtain a lock on the same object in all cases so for example synchronized(bla){...}
I'd ask why you think it's necessary to load these lazily. If it's a web app, and you know you need these objects, why would you not want to load them eagerly once the app started up?
Please explain the benefit that lazy loading is providing. If it's static, is there ever a possibility that you won't initialize these objects? If the answer is no, I'd challenge the design and recommend that you load eagerly on start-up.

Categories