Is there a functional difference between initializing singleton in a getInstance() method, or in the instance...
up vote
2
down vote
favorite
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?
java android singleton
add a comment |
up vote
2
down vote
favorite
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?
java android singleton
1
The first method is not thread safe. See also "Double-Checked" Locking is Broken. I would prefer an enum implementation though.
– Elliott Frisch
Nov 10 at 18:41
Neither of these is singleton because the classes still have default public constructors.
– Onik
Nov 10 at 19:02
Yes, @Onik is correct. You need a private constructor to make sure there won't be additional copies of the Singleton
– Francisco Delmar Kurpiel
Nov 10 at 19:47
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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?
java android singleton
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?
java android singleton
java android singleton
asked Nov 10 at 18:40
lbenedetto
527315
527315
1
The first method is not thread safe. See also "Double-Checked" Locking is Broken. I would prefer an enum implementation though.
– Elliott Frisch
Nov 10 at 18:41
Neither of these is singleton because the classes still have default public constructors.
– Onik
Nov 10 at 19:02
Yes, @Onik is correct. You need a private constructor to make sure there won't be additional copies of the Singleton
– Francisco Delmar Kurpiel
Nov 10 at 19:47
add a comment |
1
The first method is not thread safe. See also "Double-Checked" Locking is Broken. I would prefer an enum implementation though.
– Elliott Frisch
Nov 10 at 18:41
Neither of these is singleton because the classes still have default public constructors.
– Onik
Nov 10 at 19:02
Yes, @Onik is correct. You need a private constructor to make sure there won't be additional copies of the Singleton
– Francisco Delmar Kurpiel
Nov 10 at 19:47
1
1
The first method is not thread safe. See also "Double-Checked" Locking is Broken. I would prefer an enum implementation though.
– Elliott Frisch
Nov 10 at 18:41
The first method is not thread safe. See also "Double-Checked" Locking is Broken. I would prefer an enum implementation though.
– Elliott Frisch
Nov 10 at 18:41
Neither of these is singleton because the classes still have default public constructors.
– Onik
Nov 10 at 19:02
Neither of these is singleton because the classes still have default public constructors.
– Onik
Nov 10 at 19:02
Yes, @Onik is correct. You need a private constructor to make sure there won't be additional copies of the Singleton
– Francisco Delmar Kurpiel
Nov 10 at 19:47
Yes, @Onik is correct. You need a private constructor to make sure there won't be additional copies of the Singleton
– Francisco Delmar Kurpiel
Nov 10 at 19:47
add a comment |
5 Answers
5
active
oldest
votes
up vote
2
down vote
accepted
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.
Actually, both method are lazy. Variable initialization and static constructors are involved only when the class is used. In this respect both are equivalent.
– Francisco Delmar Kurpiel
Nov 10 at 18:58
@FranciscoDelmarKurpiel No, Static variables are initialized only once , at the start of the execution . see stackoverflow.com/a/8704858/2040375
– Majid
Nov 10 at 19:05
That answer have a few inaccuracies, as the comments show, including this aspect. Java will initialize only your main class, were main sits, and, as you make references to other classes the class loader will initialize static variables and run static initializers for the classes being referenced. Of course, class initialization is JVM-dependent, but both Oracle and jdk work like this. It's quite easy to test, just put a breakpoint on the Singleton's constructor and write a main on a different class that either don't get the Singleton or delays getting it by, say, 10 seconds.
– Francisco Delmar Kurpiel
Nov 10 at 19:40
I did some experimentation, and it turns out I was wrong. At least in the settings I tested the initialization of the static variable happened in parallel with the execution of main. I'll post more details in my answer.
– Francisco Delmar Kurpiel
Nov 11 at 18:36
@FranciscoDelmarKurpiel So, please upvote my answer! :D
– Majid
Nov 11 at 19:35
add a comment |
up vote
2
down vote
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.
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
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
add a comment |
up vote
0
down vote
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
This implementation have a synchronization bug, as the author discloses, and the use of volatile will result in the code generated always reading from RAM, never reusing the value from registers. In my opinion correctness is always more important than a few nanoseconds, even when main go of an app is performance.
– Francisco Delmar Kurpiel
Nov 10 at 22:37
Which sync bug do you mean? I am not aware that my code example should have a bug.
– Heri
Nov 11 at 10:59
Two or more threads may pass the if statement, all of them testing true. The threads will, one at a time create a new instance of the Singleton (that won't be a Singleton anymore), each thread returning a different instance and overriding the stored value on the "instance" member. Also, you are using a publicly available monitor, so you might end up having a deadlock.
– Francisco Delmar Kurpiel
Nov 11 at 11:28
Oops, yes you are right. Forgot to insert the second null check. Corrected my post.
– Heri
Nov 11 at 11:39
I'm sorry, but now you might return partially initialized instances. Just Google "Java double checked lock". This is an anti-pattern and should be avoided. You can make it work by using volatile and an additional local variable, but I ask why you you do it. In my opinion it is never worth it.
– Francisco Delmar Kurpiel
Nov 11 at 12:10
|
show 6 more comments
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
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.
Actually, both method are lazy. Variable initialization and static constructors are involved only when the class is used. In this respect both are equivalent.
– Francisco Delmar Kurpiel
Nov 10 at 18:58
@FranciscoDelmarKurpiel No, Static variables are initialized only once , at the start of the execution . see stackoverflow.com/a/8704858/2040375
– Majid
Nov 10 at 19:05
That answer have a few inaccuracies, as the comments show, including this aspect. Java will initialize only your main class, were main sits, and, as you make references to other classes the class loader will initialize static variables and run static initializers for the classes being referenced. Of course, class initialization is JVM-dependent, but both Oracle and jdk work like this. It's quite easy to test, just put a breakpoint on the Singleton's constructor and write a main on a different class that either don't get the Singleton or delays getting it by, say, 10 seconds.
– Francisco Delmar Kurpiel
Nov 10 at 19:40
I did some experimentation, and it turns out I was wrong. At least in the settings I tested the initialization of the static variable happened in parallel with the execution of main. I'll post more details in my answer.
– Francisco Delmar Kurpiel
Nov 11 at 18:36
@FranciscoDelmarKurpiel So, please upvote my answer! :D
– Majid
Nov 11 at 19:35
add a comment |
up vote
2
down vote
accepted
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.
Actually, both method are lazy. Variable initialization and static constructors are involved only when the class is used. In this respect both are equivalent.
– Francisco Delmar Kurpiel
Nov 10 at 18:58
@FranciscoDelmarKurpiel No, Static variables are initialized only once , at the start of the execution . see stackoverflow.com/a/8704858/2040375
– Majid
Nov 10 at 19:05
That answer have a few inaccuracies, as the comments show, including this aspect. Java will initialize only your main class, were main sits, and, as you make references to other classes the class loader will initialize static variables and run static initializers for the classes being referenced. Of course, class initialization is JVM-dependent, but both Oracle and jdk work like this. It's quite easy to test, just put a breakpoint on the Singleton's constructor and write a main on a different class that either don't get the Singleton or delays getting it by, say, 10 seconds.
– Francisco Delmar Kurpiel
Nov 10 at 19:40
I did some experimentation, and it turns out I was wrong. At least in the settings I tested the initialization of the static variable happened in parallel with the execution of main. I'll post more details in my answer.
– Francisco Delmar Kurpiel
Nov 11 at 18:36
@FranciscoDelmarKurpiel So, please upvote my answer! :D
– Majid
Nov 11 at 19:35
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
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 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.
edited Nov 11 at 19:34
answered Nov 10 at 18:46
Majid
7,74685498
7,74685498
Actually, both method are lazy. Variable initialization and static constructors are involved only when the class is used. In this respect both are equivalent.
– Francisco Delmar Kurpiel
Nov 10 at 18:58
@FranciscoDelmarKurpiel No, Static variables are initialized only once , at the start of the execution . see stackoverflow.com/a/8704858/2040375
– Majid
Nov 10 at 19:05
That answer have a few inaccuracies, as the comments show, including this aspect. Java will initialize only your main class, were main sits, and, as you make references to other classes the class loader will initialize static variables and run static initializers for the classes being referenced. Of course, class initialization is JVM-dependent, but both Oracle and jdk work like this. It's quite easy to test, just put a breakpoint on the Singleton's constructor and write a main on a different class that either don't get the Singleton or delays getting it by, say, 10 seconds.
– Francisco Delmar Kurpiel
Nov 10 at 19:40
I did some experimentation, and it turns out I was wrong. At least in the settings I tested the initialization of the static variable happened in parallel with the execution of main. I'll post more details in my answer.
– Francisco Delmar Kurpiel
Nov 11 at 18:36
@FranciscoDelmarKurpiel So, please upvote my answer! :D
– Majid
Nov 11 at 19:35
add a comment |
Actually, both method are lazy. Variable initialization and static constructors are involved only when the class is used. In this respect both are equivalent.
– Francisco Delmar Kurpiel
Nov 10 at 18:58
@FranciscoDelmarKurpiel No, Static variables are initialized only once , at the start of the execution . see stackoverflow.com/a/8704858/2040375
– Majid
Nov 10 at 19:05
That answer have a few inaccuracies, as the comments show, including this aspect. Java will initialize only your main class, were main sits, and, as you make references to other classes the class loader will initialize static variables and run static initializers for the classes being referenced. Of course, class initialization is JVM-dependent, but both Oracle and jdk work like this. It's quite easy to test, just put a breakpoint on the Singleton's constructor and write a main on a different class that either don't get the Singleton or delays getting it by, say, 10 seconds.
– Francisco Delmar Kurpiel
Nov 10 at 19:40
I did some experimentation, and it turns out I was wrong. At least in the settings I tested the initialization of the static variable happened in parallel with the execution of main. I'll post more details in my answer.
– Francisco Delmar Kurpiel
Nov 11 at 18:36
@FranciscoDelmarKurpiel So, please upvote my answer! :D
– Majid
Nov 11 at 19:35
Actually, both method are lazy. Variable initialization and static constructors are involved only when the class is used. In this respect both are equivalent.
– Francisco Delmar Kurpiel
Nov 10 at 18:58
Actually, both method are lazy. Variable initialization and static constructors are involved only when the class is used. In this respect both are equivalent.
– Francisco Delmar Kurpiel
Nov 10 at 18:58
@FranciscoDelmarKurpiel No, Static variables are initialized only once , at the start of the execution . see stackoverflow.com/a/8704858/2040375
– Majid
Nov 10 at 19:05
@FranciscoDelmarKurpiel No, Static variables are initialized only once , at the start of the execution . see stackoverflow.com/a/8704858/2040375
– Majid
Nov 10 at 19:05
That answer have a few inaccuracies, as the comments show, including this aspect. Java will initialize only your main class, were main sits, and, as you make references to other classes the class loader will initialize static variables and run static initializers for the classes being referenced. Of course, class initialization is JVM-dependent, but both Oracle and jdk work like this. It's quite easy to test, just put a breakpoint on the Singleton's constructor and write a main on a different class that either don't get the Singleton or delays getting it by, say, 10 seconds.
– Francisco Delmar Kurpiel
Nov 10 at 19:40
That answer have a few inaccuracies, as the comments show, including this aspect. Java will initialize only your main class, were main sits, and, as you make references to other classes the class loader will initialize static variables and run static initializers for the classes being referenced. Of course, class initialization is JVM-dependent, but both Oracle and jdk work like this. It's quite easy to test, just put a breakpoint on the Singleton's constructor and write a main on a different class that either don't get the Singleton or delays getting it by, say, 10 seconds.
– Francisco Delmar Kurpiel
Nov 10 at 19:40
I did some experimentation, and it turns out I was wrong. At least in the settings I tested the initialization of the static variable happened in parallel with the execution of main. I'll post more details in my answer.
– Francisco Delmar Kurpiel
Nov 11 at 18:36
I did some experimentation, and it turns out I was wrong. At least in the settings I tested the initialization of the static variable happened in parallel with the execution of main. I'll post more details in my answer.
– Francisco Delmar Kurpiel
Nov 11 at 18:36
@FranciscoDelmarKurpiel So, please upvote my answer! :D
– Majid
Nov 11 at 19:35
@FranciscoDelmarKurpiel So, please upvote my answer! :D
– Majid
Nov 11 at 19:35
add a comment |
up vote
2
down vote
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.
add a comment |
up vote
2
down vote
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.
add a comment |
up vote
2
down vote
up vote
2
down vote
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.
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.
edited Nov 11 at 18:47
answered Nov 10 at 18:56
Francisco Delmar Kurpiel
199112
199112
add a comment |
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
up vote
1
down vote
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.
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.
answered Nov 10 at 18:44
John Bollinger
76.6k63771
76.6k63771
add a comment |
add a comment |
up vote
1
down vote
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
add a comment |
up vote
1
down vote
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
add a comment |
up vote
1
down vote
up vote
1
down vote
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
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
edited Nov 10 at 18:52
answered Nov 10 at 18:46
Sand
6529
6529
add a comment |
add a comment |
up vote
0
down vote
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
This implementation have a synchronization bug, as the author discloses, and the use of volatile will result in the code generated always reading from RAM, never reusing the value from registers. In my opinion correctness is always more important than a few nanoseconds, even when main go of an app is performance.
– Francisco Delmar Kurpiel
Nov 10 at 22:37
Which sync bug do you mean? I am not aware that my code example should have a bug.
– Heri
Nov 11 at 10:59
Two or more threads may pass the if statement, all of them testing true. The threads will, one at a time create a new instance of the Singleton (that won't be a Singleton anymore), each thread returning a different instance and overriding the stored value on the "instance" member. Also, you are using a publicly available monitor, so you might end up having a deadlock.
– Francisco Delmar Kurpiel
Nov 11 at 11:28
Oops, yes you are right. Forgot to insert the second null check. Corrected my post.
– Heri
Nov 11 at 11:39
I'm sorry, but now you might return partially initialized instances. Just Google "Java double checked lock". This is an anti-pattern and should be avoided. You can make it work by using volatile and an additional local variable, but I ask why you you do it. In my opinion it is never worth it.
– Francisco Delmar Kurpiel
Nov 11 at 12:10
|
show 6 more comments
up vote
0
down vote
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
This implementation have a synchronization bug, as the author discloses, and the use of volatile will result in the code generated always reading from RAM, never reusing the value from registers. In my opinion correctness is always more important than a few nanoseconds, even when main go of an app is performance.
– Francisco Delmar Kurpiel
Nov 10 at 22:37
Which sync bug do you mean? I am not aware that my code example should have a bug.
– Heri
Nov 11 at 10:59
Two or more threads may pass the if statement, all of them testing true. The threads will, one at a time create a new instance of the Singleton (that won't be a Singleton anymore), each thread returning a different instance and overriding the stored value on the "instance" member. Also, you are using a publicly available monitor, so you might end up having a deadlock.
– Francisco Delmar Kurpiel
Nov 11 at 11:28
Oops, yes you are right. Forgot to insert the second null check. Corrected my post.
– Heri
Nov 11 at 11:39
I'm sorry, but now you might return partially initialized instances. Just Google "Java double checked lock". This is an anti-pattern and should be avoided. You can make it work by using volatile and an additional local variable, but I ask why you you do it. In my opinion it is never worth it.
– Francisco Delmar Kurpiel
Nov 11 at 12:10
|
show 6 more comments
up vote
0
down vote
up vote
0
down vote
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
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
edited Nov 13 at 7:07
answered Nov 10 at 20:50
Heri
2,65111735
2,65111735
This implementation have a synchronization bug, as the author discloses, and the use of volatile will result in the code generated always reading from RAM, never reusing the value from registers. In my opinion correctness is always more important than a few nanoseconds, even when main go of an app is performance.
– Francisco Delmar Kurpiel
Nov 10 at 22:37
Which sync bug do you mean? I am not aware that my code example should have a bug.
– Heri
Nov 11 at 10:59
Two or more threads may pass the if statement, all of them testing true. The threads will, one at a time create a new instance of the Singleton (that won't be a Singleton anymore), each thread returning a different instance and overriding the stored value on the "instance" member. Also, you are using a publicly available monitor, so you might end up having a deadlock.
– Francisco Delmar Kurpiel
Nov 11 at 11:28
Oops, yes you are right. Forgot to insert the second null check. Corrected my post.
– Heri
Nov 11 at 11:39
I'm sorry, but now you might return partially initialized instances. Just Google "Java double checked lock". This is an anti-pattern and should be avoided. You can make it work by using volatile and an additional local variable, but I ask why you you do it. In my opinion it is never worth it.
– Francisco Delmar Kurpiel
Nov 11 at 12:10
|
show 6 more comments
This implementation have a synchronization bug, as the author discloses, and the use of volatile will result in the code generated always reading from RAM, never reusing the value from registers. In my opinion correctness is always more important than a few nanoseconds, even when main go of an app is performance.
– Francisco Delmar Kurpiel
Nov 10 at 22:37
Which sync bug do you mean? I am not aware that my code example should have a bug.
– Heri
Nov 11 at 10:59
Two or more threads may pass the if statement, all of them testing true. The threads will, one at a time create a new instance of the Singleton (that won't be a Singleton anymore), each thread returning a different instance and overriding the stored value on the "instance" member. Also, you are using a publicly available monitor, so you might end up having a deadlock.
– Francisco Delmar Kurpiel
Nov 11 at 11:28
Oops, yes you are right. Forgot to insert the second null check. Corrected my post.
– Heri
Nov 11 at 11:39
I'm sorry, but now you might return partially initialized instances. Just Google "Java double checked lock". This is an anti-pattern and should be avoided. You can make it work by using volatile and an additional local variable, but I ask why you you do it. In my opinion it is never worth it.
– Francisco Delmar Kurpiel
Nov 11 at 12:10
This implementation have a synchronization bug, as the author discloses, and the use of volatile will result in the code generated always reading from RAM, never reusing the value from registers. In my opinion correctness is always more important than a few nanoseconds, even when main go of an app is performance.
– Francisco Delmar Kurpiel
Nov 10 at 22:37
This implementation have a synchronization bug, as the author discloses, and the use of volatile will result in the code generated always reading from RAM, never reusing the value from registers. In my opinion correctness is always more important than a few nanoseconds, even when main go of an app is performance.
– Francisco Delmar Kurpiel
Nov 10 at 22:37
Which sync bug do you mean? I am not aware that my code example should have a bug.
– Heri
Nov 11 at 10:59
Which sync bug do you mean? I am not aware that my code example should have a bug.
– Heri
Nov 11 at 10:59
Two or more threads may pass the if statement, all of them testing true. The threads will, one at a time create a new instance of the Singleton (that won't be a Singleton anymore), each thread returning a different instance and overriding the stored value on the "instance" member. Also, you are using a publicly available monitor, so you might end up having a deadlock.
– Francisco Delmar Kurpiel
Nov 11 at 11:28
Two or more threads may pass the if statement, all of them testing true. The threads will, one at a time create a new instance of the Singleton (that won't be a Singleton anymore), each thread returning a different instance and overriding the stored value on the "instance" member. Also, you are using a publicly available monitor, so you might end up having a deadlock.
– Francisco Delmar Kurpiel
Nov 11 at 11:28
Oops, yes you are right. Forgot to insert the second null check. Corrected my post.
– Heri
Nov 11 at 11:39
Oops, yes you are right. Forgot to insert the second null check. Corrected my post.
– Heri
Nov 11 at 11:39
I'm sorry, but now you might return partially initialized instances. Just Google "Java double checked lock". This is an anti-pattern and should be avoided. You can make it work by using volatile and an additional local variable, but I ask why you you do it. In my opinion it is never worth it.
– Francisco Delmar Kurpiel
Nov 11 at 12:10
I'm sorry, but now you might return partially initialized instances. Just Google "Java double checked lock". This is an anti-pattern and should be avoided. You can make it work by using volatile and an additional local variable, but I ask why you you do it. In my opinion it is never worth it.
– Francisco Delmar Kurpiel
Nov 11 at 12:10
|
show 6 more comments
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242220%2fis-there-a-functional-difference-between-initializing-singleton-in-a-getinstance%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
The first method is not thread safe. See also "Double-Checked" Locking is Broken. I would prefer an enum implementation though.
– Elliott Frisch
Nov 10 at 18:41
Neither of these is singleton because the classes still have default public constructors.
– Onik
Nov 10 at 19:02
Yes, @Onik is correct. You need a private constructor to make sure there won't be additional copies of the Singleton
– Francisco Delmar Kurpiel
Nov 10 at 19:47