I am going through Java Memory Model video presentation and author is saying it is better to use Static Lazy Initialization compared to Lazy Initialization and I do not clear understand what he wants to say.
I wanted to reach to community and would appreciate if someone can explain difference between Static Lazy Initialization and Lazy Initialization with simple java code example.
Reference: Advanced Programming Topics - Java Memory Model
Well both implementations can be static so that is the first misunderstanding. The presenter in this video is explaining how you can exploit the thread-safety of class initialization.
Class initialization is inherently thread-safe and if you can have an object initialized on class initialization the object creation too are thread-safe.
Here is an example of a thread-safe statically initialized object
public class MySingletonClass{
private MySingletonClass(){
}
public static MySingletonClass getInstance(){
return IntiailizationOnDemandClassholder.instance;
}
private static class IntiailizationOnDemandClassHolder{
private static final MySingletonClass instance = new MySingletonClass();
}
}
What is important to know here, MySingletonClass instance variable will never be created and or initialized until getInstance() is invoked. And again since class initialization is thread-safe the instance variable of IntiailizationOnDemandClassholder will be loaded safely, once and is visible to all threads.
To answer your edit depends on your other type of implementation. If you want to do double-checked-locking your instance variable would need to be volatile. If you do not want DCL then you will need to synchronize access each time to your variable. Here are the two examples:
public class DCLLazySingleton{
private static volatile DCLLazySingleton instance;
public static DCLLazySingleton getInstace(){
if(instance == null){
synchronized(DCLLazySingleton.class){
if(instance == null)
instance=new DCLLazySingleton();
}
}
return instance;
}
and
public class ThreadSafeLazySingleton{
private static ThreadSafeLazySingleton instance;
public static ThreadSafeLazySingleton getInstance(){
synchronized(ThreadSafeLazySingleton.class){
if(instance == null){
instance = new ThreadSafeLazySingleton();
}
return instance;
}
}
The last example requires a lock acquisition on every request of the instance. The second example requires a volatile-read on each access (may be cheap or not, depends on the CPU).
The first example will always lock once regardless of the CPU. Not only that but each read will be a normal without any need to worry about thread-safety. I personally like the first example I have listed.
I think the author in the presentation refers to the fact that a static field would be initialized only once in a thread-safe way at the first use of the class which contains that field (this is guaranteed by JMM):
class StaticLazyExample1 {
static Helper helper = new Helper();
static Helper getHelper() {
return helper;
}
}
Here helper field would be initialized upon first usage of StaticLazyExample1 class (i.e. upon constructor or static method call)
There is also Initialization On Demand Holder idiom, which is based on static lazy initialization:
class StaticLazyExample2 {
private static class LazyHolder {
public static Helper instance = new Helper();
}
public static Helper getHelper() {
return LazyHolder.instance;
}
}
Here a Helper instance would be created only upon first call to StaticLazyExample2.getHelper() static method. This code is guaranteed to be thread-safe and correct because of the initialization guarantees for static fields; if a field is set in a static initializer, it is guaranteed to be made visible, correctly, to any thread that accesses that class.
UPDATE
What is the difference between both types of initialization?
The static lazy initialization provides efficient thread safe lazy initialization of the static fields and has zero synchronization overhead.
On the other hand if you would like to lazily initialize a non-static field, you should write something like this:
class LazyInitExample1 {
private Helper instance;
public synchronized Helper getHelper() {
if (instance == null) instance == new Helper();
return instance;
}
}
Or use Double-Cheked Locking idiom:
class LazyInitExample2 {
private volatile Helper helper;
public Helper getHelper() {
if (helper == null) {
synchronized (this) {
if (helper == null) helper = new Helper();
}
}
return helper;
}
}
Should I mention they both require explicit synchronization and carry additional timing overhead comparing to static lazy initialization?
It is worth noting that the simplest thread safe static lazy initialisation is to use an enum This works because initialisation of static fields is thread safe and classes are lazily loaded anyway.
enum ThreadSafeLazyLoadedSingleton {
INSTANCE;
}
A class which uses a lazy loaded value is String. The hashCode is only computed the first time it is used. After that the cached hashCode is used.
I don't think you can say that one is better than the other because they are not really interchangeable.
A reference would be good here, for sure. They both have the same basic idea: Why allocate resources (memory, cpu) if you don't have to? Instead, defer allocation of those resources until they're actually needed. This can be good in intensive environments to avoid waste, but can be very bad if you need the results right now and cannot wait. Adding a "lazy but prudent" system is very difficult (one that detects downtime and runs these lazy calculations when it gets free time.)
Here's an example of lazy initialization.
class Lazy {
String value;
int computed;
Lazy(String s) { this.value = s; }
int compute() {
if(computed == 0) computed = value.length();
return computed;
}
}
Here's static lazy initializtion
class StaticLazy {
private StaticLazy staticLazy;
static StaticLazy getInstance() {
if(staticLazy == null) staticLazy = new StaticLazy();
return staticLazy;
}
}
The distinction is the mechanism you implement the lazy initialization. By Static Lazy Initialization I assume the presenter means this solution which relies on the JVM being compliant with any version of Java (see 12.4 Initialization of Classes and Interfaces, of the Java Language Specification).
Lazy Initialization probably means lazy initialization described in many other answers to this question. Such initialization mechanisms make assumptions about the JVM that are not thread-safe until Java 5 (as Java 5 has a real memory model specification).
Lazy loading is just a fancy name given to the process of initializing a class when it’s actually needed.
In simple words, Lazy loading is a software design pattern where the initialization of an object occurs only when it is actually needed and not before to preserve simplicity of usage and improve performance.
Lazy loading is essential when the cost of object creation is very high and the use of the object is very rare. So this is the scenario where it’s worth implementing lazy loading.The fundamental idea of lazy loading is to load object/data when needed.
Source: https://www.geeksforgeeks.org/lazy-loading-design-pattern/
Related
I am reading about Singleton design pattern and evaluating different implementations. I have doubt with the below implementations:
A. Singleton Implementation with static inner class
public class SingletonWithStaticClass {
private SingletonWithStaticClass(){}
private static class SingletonInnerClass{
public static SingletonWithStaticClass INSTANCE = new SingletonWithStaticClass();
}
public static SingletonWithStaticClass getInstance(){
return SingletonInnerClass.INSTANCE;
}
}
B. Singleton double checked locking
public class SingletonWithDoubleCheck {
private static SingletonWithDoubleCheck INSTANCE = null;
private SingletonWithDoubleCheck(){
if(INSTANCE != null){
throw new RuntimeException("Accessing private constructor is prohibited. Use getInstance method instead");
}
}
public static SingletonWithDoubleCheck getInstance(){
if(INSTANCE == null){
synchronized (SingletonWithDoubleCheck.class) {
if(INSTANCE == null){
INSTANCE = new SingletonWithDoubleCheck();
}
}
}
return INSTANCE;
}
}
Which one is better?
I feel we can access the private constructor with Reflection in first implementation where as second implementation is safe (From Reflection attack).
However, I am not going to use any of these in my production code, I will use enum instead. But out of these two, isn't the first implementation is broken when considered Reflection attack?
Please correct me if my understanding is wrong.
Both are overly complicated. The first was the best option before Java 5.0, however the second was never a good option. It didn't work before Java 5.0, it requires a volatile field and after this version you could use enum
I prefer using an enum to define a class with exactly one instance. It is a final class, thread safe, lazy loaded, and has a private constructor.
enum Singleon {
INSTANCE;
}
The double locking singleton is only useful if you must provide configuration information in it's construction. In this case, I prefer to use Dependency Injection to provide/configure singletons and only have stateless Singletons which don't require configuration.
Neither are good - and attempting to compare them using different scales is counter-productive.
The first is unnecessarily complex and, as you say, is open to reflection hacking, but so is the other one, just slightly less so.
The second uses a synchronized which comes with a cost.
I've been wondering about singletons in Java. By convention, a singleton is set up something like this:
private static MyClass instance = null;
public static MyClass getInstance(){
if (instance == null){
instance = new MyClass();
}
return instance;
}
private MyClass(){}
Recently I've switched to using the following:
public static final MyClass instance = new MyClass();
private MyClass(){}
This is a lot shorter, faster as there's no null-check, and typing MyClass.instance feels nicer to me than typing MyClass.getInstance(). Is there any reason why the second is not the mainstream way to do this?
The first version creates the instance the first time it is actually needed, while the second (the shorter) runs the constructor as soon as the class is initialized
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 (§7.6), and an assert statement (§14.10)
lexically nested within T (§8.1.3) is executed. [...]
Invocation of certain reflective methods in class Class and in
package java.lang.reflect also causes class or interface initialization.
The initialization upon first usage is a performance improvement that may speed up the startup of the application if the code in the constructor makes expensive operations. On the other hand, the second version is straightforward to read and is automatically thread-safe.
Anyway, the state of the art is not creating singleton in either ways: for a bunch of KB you can get dependency injection libraries that make it working for you, and also handle more complex scenarios (for example look at Spring and AOP-backed injection).
Note: the first version is not thread safe in the pasted snippet
The way you have first described is known as lazy instantiation, i.e the object will only be created when it is first called. This method is not thread-safe as it is possible for a second thread to create a second instance.
If you read the following book:
Effective Java by Joshua Bloch
He explains that the best implementation of the singleton pattern is through the use of an Enum :
public enum Singleton {
INSTANCE;
public void doSomething() {
...
}
}
Then you would call your singleton through the Enum as follows:
public class Test {
public void test(){
Singleton.INSTANCE.doSomething();
}
}
This fits nicely with what you are saying in terms of it looks nicer and shorter to write but also guarantees there can never be a second instance.
I can think of two reasons:
The first is Encapsulation: you might have second thoughts about how and when your singleton is initialized, after your class has been exposed to client code. And an initialization method gives you more freedom as to changing your strategy later on. For example you might change your mind and decide to use two different constructors instead of one, according to another static variable's value at runtime. With your solution you're bound to using just one constructor at the time your class is loaded into memory, whereas with getInstance() you can change the initialization logic without affecting the interface to the client code.
The second is Lazy Initialization : with the conventional singleton implementation the MyClass object is loaded into memory only when needed by the client code for the first time. And if the client code doesn't need it at all, you save on the memory allocated by your application. Note that whether your singleton is needed or not might not be certain until the program runs. For example it might depend on the user interaction with the program.
However the Lazy Initialization is not something you might necessarily want. For example if you're programming an interactive system and the initialization of your singleton is time consuming, it might actually be better to initialize it when the program is loading rather than when the user is already interacting with it, cause the latter might cause a latency in your system response the first time getInstance() is called. But in this case you can just have your instance initialized with the public method as in:
private static MyClass instance = getInstance();
The best way to synchronize the threads is using Double Checked (to ensure that only one thread will enter the synchronized block at a time and to avoid obtaining the lock every time the code is executed).
public class DoubleCheckLocking {
public static class SearchBox {
private static volatile SearchBox searchBox;
// private attribute of this class
private String searchWord = "";
private String[] list = new String[]{"Stack", "Overflow"};
// private constructor
private SearchBox() {}
// static method to get instance
public static SearchBox getInstance() {
if (searchBox == null) { // first time lock
synchronized (SearchBox.class) {
if (searchBox == null) { // second time lock
searchBox = new SearchBox();
}
}
}
return searchBox;
}
}
Reflection: Reflection can be caused to destroy singleton
property of singleton class, as shown in following example:
// Java code to explain effect of Reflection
import java.lang.reflect.Constructor;
// Singleton class
class Singleton
{
// public instance initialized when loading the class
public static Singleton instance = new Singleton();
private Singleton()
{
// private constructor
}
}
public class GFG
{
public static void main(String[] args)
{
Singleton instance1 = Singleton.instance;
Singleton instance2 = null;
try
{
Constructor[] constructors =
Singleton.class.getDeclaredConstructors();
for (Constructor constructor : constructors)
{
// Below code will destroy the singleton pattern
constructor.setAccessible(true);
instance2 = (Singleton) constructor.newInstance();
break;
}
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("instance1.hashCode():- "
+ instance1.hashCode()); //366712642
System.out.println("instance2.hashCode():- "
+ instance2.hashCode()); //1829164700
}
}
I want to be sure that my Singleton instance is available safely and with minimum synchronization but I have doubt about the first if clause outside the synchronized block. Is it possible for the INSTANCE to have a not-null value when it isn't completely constructed? If so how can I solve the issue.
I think that including the whole get() block will reduce the efficiency because there will be so many configuration variables that must be read thousands of times per second from different part of program via this get() method.
public class ConfsDBLoader {
private static ConfsDBLoader INSTANCE = null;
private static final Object lock = new Object();
private ConfsDBLoader() { //Codes loading the db objects
}
public static ConfsDBLoader get(){
if(INSTANCE != null){
return INSTANCE;
} else {
synchronized(lock){
if(INSTANCE == null){
INSTANCE = new ConfsDBLoader();
}
return INSTANCE;
}
}
}
}
NOTE: I cant use static initialization because my hibernate sessionFactory is initialized statically and I want to have complex static structures that need each other. In fact I already have it and I'm not interested to make it more and more complex and investigate where these these static attributes try to use each other.
No. There is not enough synchronization to make sure that you are seeing the correct value on INSTANCE. You may see a non-null, but corrupt instance if your ConfsDBLoader because it may not be properly constructed by the time another thread calls getInstance().
You have 3 choices:
Eager initialize and make final
Synchronize whole method
Make INSTANCE volatile
By using a volatile boolean that is read only if the instance is null, can I avoid the default/frequent volatile read once the instance is initailized like so? Havent seen anyone recommend double checked locking like this, but seems to avoid volatile reads once fully initialized...
public class Singleton {
private static volatile boolean initialized = false;
private static Object lock = new Object();
private static Singleton instance;
public static Singleton getInstance(){
if(instance != null) return instance;
if(!initialized){
synchronized(lock){
if(!initialized){
instance = new Singleton();
initialized = true;
}
}
}
return instance;
}
}
No, you cannot. If thread A has reached the synchronized block and is executing the
instance = new Singleton();
line, a thread B entering your function could see instance as initialized before thread A has finished constructing the object. So you risk having thread B try to work on a partially constructed object.
See the DLCP article for variations and explanations on this pattern.
Your optimization attempt is not only premature, but also fruitless, quoting Are volatile variable 'reads' as fast as normal reads?:
On an x86, there is no additional overhead associated with volatile reads.
If you want lazy instantiation but concerned about performance, use "inner class" approach - it is cleaner and shorter (and a tiny bit more efficient as well). Something like that:
public class Singleton {
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}
The trick is that instance is created during initialization of the inner class - that will happen when class is first referenced, which is first call to getInstance().
BTW - avoid such "static" singletons, unless there are truly good reasons to use them.
volatile read is (almost) free on most hardware, volatile write is expensive, though... So why bother?
The short answer is no. between instance = new Singleton() and initialized = true on a weak memory model where stores can be reordered a reader might see an uninitialized Signleton.
on x86 and sparc TSO no store-store reorder but on ARM and IA64 it does happen.
I understand that double locking in Java is broken, so what are the best ways to make Singletons Thread Safe in Java? The first thing that springs to my mind is:
class Singleton{
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null) instance = new Singleton();
return instance;
}
}
Does this work? if so, is it the best way (I guess that depends on circumstances, so stating when a particular technique is best, would be useful)
Josh Bloch recommends using a single-element enum type to implement singletons (see Effective Java 2nd Edition, Item 3: Enforce the singleton property with a private constructor or an enum type).
Some people think this is a hack, since it doesn't clearly convey intent, but it does work.
The following example is taken straight from the book.
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
Here is his closing arguments:
This approach [...] is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiations, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.
On enum constant singleton guarantee
JLS 8.9. Enums
An enum type has no instances other than those defined by its enum constants. It is a compile-time error to attempt to explicitly instantiate an enum type (§15.9.1).
The final clone method in Enum ensures that enum constants can never be cloned, and the special treatment by the serialization mechanism ensures that duplicate instances are never created as a result of deserialization. Reflective instantiation of enum types is prohibited. Together, these four things ensure that no instances of an enum type exist beyond those defined by the enum constants.
On lazy initialization
The following snippet:
public class LazyElvis {
enum Elvis {
THE_ONE;
Elvis() {
System.out.println("I'M STILL ALIVE!!!");
}
}
public static void main(String[] args) {
System.out.println("La-dee-daaa...");
System.out.println(Elvis.THE_ONE);
}
}
Produces the following output:
La-dee-daaa...
I'M STILL ALIVE!!!
THE_ONE
As you can see, THE_ONE constant is not instantiated through the constructor until the first time it's accessed.
I see no problem with your implementation (other than the fact that the lock for the singleton-monitor may be used by other methods, for other reasons, and thus, unnecessarily, prevent some other thread from getting the instance). This could be avoided by introducing an extra Object lock to lock on.
This Wikipedia article suggests another method:
public class Something {
private Something() {
}
private static class LazyHolder {
private static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
From the article:
This implementation is a well-performing and concurrent implementation valid in all versions of Java.
...
The implementation relies on the well-specified initialization phase of execution within the Java Virtual Machine (JVM); see section 12.4 of Java Language Specification (JLS) for details.
My preference is to just do:
class Singleton {
private static final INSTANCE = new Singleton();
private Singleton(){}
public Singleton instance(){
return INSTANCE;
}
}
It is rare that you need lazy initialization. You should always start with eager initialization and only change to lazy initialization if you see problems. Unless you have measured and pinpointed Singleton instantiation as the culprit of performance problem, just use eager initialization. It's simpler and more performant.
You could use enum for sure, but personally I don't bother because the benefit over normal eager instantiation is security (against reflection attack), and most of the time my code is vulnerable to such attacks anyways :p
Josh Bloch recommends 2 solutions:
1) worser:
class Singleton {
public static Singleton instance = new Singleton();
...
}
2) better:
public enum Singleton {
INSTANCE;
...
}
You can use this snippet of code from wiki
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}