Below show is the creation on the singleton object.
public class Map_en_US extends mapTree {
private static Map_en_US m_instance;
private Map_en_US() {}
static{
m_instance = new Map_en_US();
m_instance.init();
}
public static Map_en_US getInstance(){
return m_instance;
}
#Override
protected void init() {
//some code;
}
}
My question is what is the reason for using a static block for instantiating. i am familiar with below form of instantiation of the singleton.
public static Map_en_US getInstance(){
if(m_instance==null)
m_instance = new Map_en_US();
}
The reason is thread safety.
The form you said you are familiar with has the potential of initializing the singleton a large number of times. Moreover, even after it has been initialized multiple times, future calls to getInstance() by different threads might return different instances! Also, one thread might see a partially-initialized singleton instance! (let's say the constructor connects to a DB and authenticates; one thread might be able to get a reference to the singleton before the authentication happens, even if it is done in the constructor!)
There are some difficulties when dealing with threads:
Concurrency: they have to potential to execute concurrently;
Visibility: modifications to the memory made by one thread might not be visible to other threads;
Reordering: the order in which the code is executed cannot be predicted, which can lead to very strange results.
You should study about these difficulties to understand precisely why those odd behaviors are perfectly legal in the JVM, why they are actually good, and how to protect from them.
The static block is guaranteed, by the JVM, to be executed only once (unless you load and initialize the class using different ClassLoaders, but the details are beyond the scope of this question, I'd say), and by one thread only, and the results of it are guaranteed to be visible to every other thread.
That's why you should initialize the singleton on the static block.
My preferred pattern: thread-safe and lazy
The pattern above will instantiate the singleton on the first time the execution sees a reference to the class Map_en_US (actually, only a reference to the class itself will load it, but might not yet initialize it; for more details, check the reference). Maybe you don't want that. Maybe you want the singleton to be initialized only on the first call to Map_en_US.getInstance() (just as the pattern you said you are familiar with supposedly does).
If that's what you want, you can use the following pattern:
public class Singleton {
private Singleton() { ... }
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
In the code above, the singleton will only be instantiated when the class SingletonHolder is initialized. This will happen only once (unless, as I said before, you are using multiple ClassLoaders), the code will be executed by only one thread, the results will have no visibility problems, and the initialization will occur only on the first reference to SingletonHolder, which happens inside the getInstance() method. This is the pattern I use most often when I need a singleton.
Another patterns...
1. synchronized getInstace()
As discussed in the comments to this answer, there's another way to implement the singleton in a thread safe manner, and which is almost the same as the (broken) one you are familiar with:
public class Singleton {
private static Singleton instance;
public static synchronized getInstance() {
if (instance == null)
instance = new Singleton();
}
}
The code above is guaranteed, by the memory model, to be thread safe. The JVM specification states the following (in a more cryptic way): let L be the lock of any object, let T1 and T2 be two threads. The release of L by T1 happens-before the acquisition of L by T2.
This means that every thing that has been done by T1 before releasing the lock will be visible to every other thread after they acquire the same lock.
So, suppose T1 is the first thread that entered the getInstance() method. Until it has finished, no other thread will be able to enter the same method (since it is synchronized). It will see that instance is null, will instantiate a Singleton and store it in the field. It will then release the lock and return the instance.
Then, T2, which was waiting for the lock, will be able to acquire it and enter the method. Since it acquired the same lock that T1 just released, T2 will see that the field instance contains the exact same instance of Singleton created by T1, and will simply return it. What is more, the initialization of the singleton, which has been done by T1, happened before the release of the lock by T1, which happened before the acquisition of the lock by T2, therefore there's no way T2 can see a partially-initialized singleton.
The code above is perfectly correct. The only problem is that the access to the singleton will be serialized. If it happens a lot, it will reduce the scalability of your application. That's why I prefer the SingletonHolder pattern I showed above: access to the singleton will be truly concurrent, without the need for synchronization!
2. Double checked locking (DCL)
Often, people are scared about the cost of lock acquisition. I've read that nowadays it is not that relevant for most applications. The real problem with lock acquisition is that it hurts scalability by serializing access to the synchronized block.
Someone devised an ingenuous way to avoid acquiring a lock, and it has been called double-checked locking. The problem is that most implementations are broken. That is, most implementations are not thread-safe (ie, are as thread-unsafe as the getInstace() method on the original question).
The correct way to implement the DCL is as follows:
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
The difference between this correct and an incorrect implementation is the volatile keyword.
To understand why, let T1 and T2 be two threads. Let's first assume that the field is not volatile.
T1 enters the getInstace() method. It's the first one to ever enter it, so the field is null. It then enters the synchronized block, then the second if. It also evaluates to true, so T1 creates a new instance of the singleton and stores it in the field. The lock is then release, and the singleton is returned. For this thread, it is guaranteed that the Singleton is completely initialized.
Now, T2 enters the getInstace() method. It is possible (although not guaranteed) that it will see that instance != null. It will then skip the if block (and so it will never acquire the lock), and will directly return the instance of the Singleton. Due to reordering, it is possible that T2 will not see all the initialization performed by the Singleton in its constructor! Revisiting the db connection singleton example, T2 might see a connected but not yet authenticated singleton!
For more information...
... I'd recommend a brilliant book, Java Concurrency in Practice, and also, the Java Language Specification.
If you initialize in the getInstance() method, you can get a racing conditions, i.e. if 2 threads execute the if(m_instance == null) check simulataneously, both might see the instance be null and thus both might call m_instance = new Map_en_US();
Since the static initializer block is executed only once (by one thread that is executing the class loader), you don't have a problem there.
Here's a good overview.
How about this approach for eradicating the static block:
private static Map_en_US s_instance = new Map_en_US() {{init();}};
It does the same thing, but is way neater.
Explanation of this syntax:
The outer set of braces creates an anonymous class.
The inner set of braces is called an "instance block" - it fires during construction.
This syntax is often incorrectly called the "double brace initializer" syntax, usually by those who don't understand what is going on.
Also, note:
m_ is a naming convention prefix for instance (ie member) fields.
s_ is a naming convention prefix for class (ie static) fields.
So I changed the name of the field to s_....
It depends on how resource-intensive the init method is. If it e.g. does a lot of work, maybe you want that work done at the startup of the application instead of on the first call. Maybe it downloads the map from Internet? I don't know...
The static block is executed when the class is first loaded by the JVM. As Bruno said, that helps with thread safety because there isn't a possibility that two threads will fight over the same getInstance() call for the first time.
With static instantiation there will be only one copy of the instance per class irrespective of how many objects being created.
Second advantage with the way is, The method is thread-safeas you are not doing anything in the method except returning the instance.
the static block instances your class and call the default contructor (if any) only one time and when the application starts and all static elements are loaded by the JVM.
Using the getInstance() method the object for the class is builded and initialized when the method is called and not on the static initialization. And is not really safe if you are running the getInstance() in diferent threads at the same time.
static block is here to allow for init invocation. Other way to code it could be eg like this (which to prefer is a matter of taste)
public class Map_en_US extends mapTree {
private static
/* thread safe without final,
see VM spec 2nd ed 2.17.15 */
Map_en_US m_instance = createAndInit();
private Map_en_US() {}
public static Map_en_US getInstance(){
return m_instance;
}
#Override
protected void init() {
//some code;
}
private static Map_en_US createAndInit() {
final Map_en_US tmp = new Map_en_US();
tmp.init();
return tmp;
}
}
update corrected per VM spec 2.17.5, details in comments
// Best way to implement the singleton class in java
package com.vsspl.test1;
class STest {
private static STest ob= null;
private STest(){
System.out.println("private constructor");
}
public static STest create(){
if(ob==null)
ob = new STest();
return ob;
}
public Object clone(){
STest obb = create();
return obb;
}
}
public class SingletonTest {
public static void main(String[] args) {
STest ob1 = STest.create();
STest ob2 = STest.create();
STest ob3 = STest.create();
System.out.println("obj1 " + ob1.hashCode());
System.out.println("obj2 " + ob2.hashCode());
System.out.println("obj3 " + ob3.hashCode());
STest ob4 = (STest) ob3.clone();
STest ob5 = (STest) ob2.clone();
System.out.println("obj4 " + ob4.hashCode());
System.out.println("obj5 " + ob5.hashCode());
}
}
-------------------------------- OUT PUT -------------------------------------
private constructor
obj1 1169863946
obj2 1169863946
obj3 1169863946
obj4 1169863946
obj5 1169863946
Interesting never seen that before. Seems largely a style preference. I suppose one difference is: the static initialisation takes place at VM startup, rather than on first request for an instance, potentially eliminating an issue with concurrent instantiations? (Which can also be handled with synchronized getInstance() method declaration)
Related
I have read about many possible ways to create a singleton for the multithreaded environment in Java, like Enums, Double-check locking, etc.
I found a simple way that is also working fine and I unable to find its drawbacks or failure cases. May anyone explain when it may fail or why we should not choose this approach.
public final class MySingleton {
public final static MySingleton INSTANCE = new MySingleton();
private MySingleton(){}
}
I am testing it with the below code and working fine:
public class MyThread {
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
Thread thread = new Thread(() -> {
MySingleton singleton = MySingleton.INSTANCE;
System.out.println(singleton.hashCode() + " " + Thread.currentThread().getName());
});
thread.start();
}
}
}
Every comment is appreciated.
Your singleton is instantiated when the class is loaded, therefore when the main method is started, it is already instantiated and from a multithreading perspective is safe.
But there are some arguments why this might not be the best approach:
When instantiating your singleton throws an exception, you get a nasty classloading exception which is hard to analyze, especially when you don't have a debugger to attach.
When instantiating takes some time, so you might don't want to do this when the class is loaded in order to minimize the startup time of your application
And additionally using singletons is not a good design as you hardcode the dependency between the client (that uses this class) and the implementation of this class. So it is hard to replace your implementation with a mock for testing.
Yes, this is a fine implementation of a singleton.
The test shows... something; but it doesn't really explain whether it's working or not. What you are trying to show (that only one instance is created) is essentially impossible to show with a test, because it's something that's guaranteed by the language spec.
See JLS 12, in particular JLS 12.4, which describes how classes are initialized.
For each class or interface C, there is a unique initialization lock LC. The mapping from C to LC is left to the discretion of the Java Virtual Machine implementation. The procedure for initializing C is then as follows:
Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.
If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this step.
If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.
If the Class object for C indicates that C has already been initialized, then no further action is required. Release LC and complete normally.
...
So, classes are guaranteed to only be initialized once (if at all), because the initialization is done whilst holding a class-specific lock; the happens-before guarantees of acquiring and releasing that lock mean that the values of final fields are visible; so the INSTANCE field is guaranteed to be initialized once, and thus there is only one instance of MySingleton possible.
Note that your implementation is effectively the same as an enum:
public enum MySingleton {
INSTANCE
}
Enums are really just syntactic sugar for classes. If you decompiled an enum class, it would look something like:
public class MySingleton {
public static final MySingleton INSTANCE = new MySingleton(0);
private MySingleton(int ordinal) { ... }
}
It is perfectly fine and simple. Although you may check the trade offs listed below:
May lead to resource wastage. Because instance of class is created always, whether it is required or not.
CPU time is also wasted for creating the instance if it is not required.
Exception handling is not possible.
Also you have to be sure that MySingleton class is thread-safe
See
Java Singleton Design Pattern Practices with Examples
Ah, I ran into some problems using exactly this approach a few months ago. Most people here will tell you this is fine, and they are mostly right, as long as you know the constructor won't throw an exception. What I'm about to describe is a common but unpredictable artifact of JVM caching conventions.
I had a singleton that was set up exactly the one you show in your question. Every time I attempted to run the program I got a NoClassDefFoundError. I had no idea what was going wrong until I found this post on Reddit, aptly titled Using static initialization for singletons is bad!
Just FYI, if you initialize a singleton with static initialization, e.g., private static final MyObject instance = new MyObject(); and there's business logic in your constructor, you can easily run into weird meta-errors, like NoClassDefFoundError. Even worse, it's unpredictable. Certain conditions, such as the OS, can change whether an error occurs or not. Static initialization also includes using a static block, "static{...}" , and using the enum singleton pattern.
The post also links to some Android docs about the cause of the problem.
The solution, which worked very well for me, is called double checked locking.
public class Example {
private static volatile Example SINGLETON = null;
private static final Object LOCK = new Object();
private Example() {
// ...do stuff...
}
public static Example getInstance() {
if (SINGLETON == null) {
synchronized (LOCK) {
if (SINGLETON == null) {
SINGLETON = new Example();
}
}
}
return SINGLETON;
}
}
For the most part, you can probably do it the simple way without problems. But, if your constructor contains enough business logic that you start getting NoClassDefFoundError, this slightly more complicated approach should fix it.
Given below is a java class using Bill Pugh singleton solution.
public class Singleton {
int nonVolatileVariable;
private static class SingletonHelper {
private static Singleton INSTANCE = new Singleton();
}
private Singleton() { }
public static Singleton getInstance() {
return SingletonHelper.INSTANCE;
}
public int getNonVolatileVariable() {
return nonVolatileVariable;
}
public void setNonVolatileVariable(int nonVolatileVariable) {
this.nonVolatileVariable= nonVolatileVariable;
}
}
I have read in many places that this approach is thread safe. So if I understand it correctly, then the singleton instance is created only once and all threads accessing the getInstance method will receive the same instance of the class Singleton. However I was wondering if the threads can locally cache the obtained singleton object. Can they? If yes then doesn't that would mean that each thread can change the instance field nonVolatileVariable to different values which might create problems.
I know that there are other singleton creation methods such as enum singleton, but I am particularly interested in this singleton creation method.
So my question is that, is there a need to use the volatile keyword like
int volatile nonVolatileVariable; to make sure that the singleton using this approach is truely thread safe? Or is it already truly thread safe? If so how?
So my question is that, is there a need to use the volatile keyword
like int volatile nonVolatileVariable; to make sure that the
singleton using this approach is truly thread safe? Or is it already
truly thread safe? If so how?
The singleton pattern ensures that a single instance of the class is created. It doesn't ensures that fields and methods be thread-safe and volatile doesn't ensure it either.
However I was wondering if the threads can locally cache the obtained
singleton object ?
According to the memory model in Java, yes they can.
if yes then doesn't that would mean that each thread can change the
instance field nonVolatileVariable to different values which might
create problems.
Indeed but you would still a problem of consistency with a volatile variable because volatile handles the memory visibility question but it doesn't handle the synchronization between threads.
Try the following code where multiple threads increment a volatile int 100 times.
You will see that you could not get 100 at each time as result.
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Singleton {
volatile int volatileInt;
private static class SingletonHelper {
private static Singleton INSTANCE = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHelper.INSTANCE;
}
public int getVolatileInt() {
return volatileInt;
}
public void setVolatileInt(int volatileInt ) {
this.volatileInt = volatileInt ;
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Callable<Void>> callables = IntStream.range(0, 100)
.mapToObj(i -> {
Callable<Void> callable = () -> {
Singleton.getInstance().setVolatileInt(Singleton.getInstance().getVolatileInt()+1);
return null;
};
return callable;
})
.collect(Collectors.toList());
executorService.invokeAll(callables);
System.out.println(Singleton.getInstance().getVolatileInt());
}
}
To ensure that each thread takes into consideration other invocations, you have to use external synchronization and in this case make the variable volatile is not required.
For example :
synchronized (Singleton.getInstance()) {
Singleton.getInstance()
.setVolatileInt(Singleton.getInstance().getVolatileInt() + 1);
}
And in this case, volatile is not required any longer.
The specific guarantee of this type of singleton basically works like this:
Each class has a unique lock for class initialization.
Any action which could cause class initialization (such as accessing a static method) is required to first acquire this lock, check if the class needs to be initialized and, if so, initialize it.
If the JVM can determine that the class is already initialized and the current thread can see the effect of that, then it can skip step 2, including skipping acquiring the lock.
(This is documented in §12.4.2.)
In other words, what's guaranteed here is that all threads must at least see the effects of the assignment in private static Singleton INSTANCE = new Singleton();, and anything else that was performed during static initialization of the SingletonHelper class.
Your analysis that concurrent reads and writes of the non-volatile variable can be inconsistent between threads is correct, although the language specification isn't written in terms of caching. The way the language specification is written is that reads and writes can appear out of order. For example, suppose the following sequence of events, listed chronologically:
nonVolatileVariable is 0
ThreadA sets nonVolatileVariable to 1
ThreadB reads nonVolatileVariable (what value should it see?)
The language specification allows ThreadB to see the value 0 when it reads nonVolatileVariable, which is as if the events had happened in the following order:
nonVolatileVariable is 0
ThreadB reads nonVolatileVariable (and sees 0)
ThreadA sets nonVolatileVariable to 1
In practice, this is due to caching, but the language specification doesn't say what may or may not be cached (except here and here, as a brief mention), it only specifies the order of events.
One extra note regarding thread-safety: some actions are always considered atomic, such as reads and writes of object references (§17.7), so there are some cases where the use of a non-volatile variable can be considered thread-safe, but it depends on what you're specifically doing with it. There can still be memory inconsistency but concurrent reads and writes can't somehow interleave, so you can't end up with e.g. an invalid pointer value somehow. It's therefore sometimes safe to use non-volatile variables for e.g. lazily-initialized fields if it doesn't matter that the initialization procedure could happen more than once. I know of at least one place in the JDK where this is used, in java.lang.reflect.Field (also see this comment in the file), but it's not the norm.
What does this java code mean? Will it gain lock on all objects of MyClass?
synchronized(MyClass.class) {
//is all objects of MyClass are thread-safe now ??
}
And how the above code differs from this one:
synchronized(this) {
//is all objects of MyClass are thread-safe now ??
}
The snippet synchronized(X.class) uses the class instance as a monitor. As there is only one class instance (the object representing the class metadata at runtime) one thread can be in this block.
With synchronized(this) the block is guarded by the instance. For every instance only one thread may enter the block.
synchronized(X.class) is used to make sure that there is exactly one Thread in the block. synchronized(this) ensures that there is exactly one thread per instance. If this makes the actual code in the block thread-safe depends on the implementation. If mutate only state of the instance synchronized(this) is enough.
To add to the other answers:
static void myMethod() {
synchronized(MyClass.class) {
//code
}
}
is equivalent to
static synchronized void myMethod() {
//code
}
and
void myMethod() {
synchronized(this) {
//code
}
}
is equivalent to
synchronized void myMethod() {
//code
}
No, the first will get a lock on the class definition of MyClass, not all instances of it. However, if used in an instance, this will effectively block all other instances, since they share a single class definition.
The second will get a lock on the current instance only.
As to whether this makes your objects thread safe, that is a far more complex question - we'd need to see your code!
Yes it will (on any synchronized block/function).
I was wondering about this question for couple days for myself (actually in kotlin). I finally found good explanation and want to share it:
Class level lock prevents multiple threads to enter in synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads.
Class level locking should always be done to make static data thread safe. As we know that static keyword associate data of methods to class level, so use locking at static fields or methods to make it on class level.
Plus to notice why .class. It is just because .class is equivalent to any static variable of class similar to:
private final static Object lock = new Object();
where lock variable name is class and type is Class<T>
Read more:
https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/
Let's say I have next class:
public class Singleton{
private static Singleton _instance;
public static Singleton getInstance(){
if(_instance == null){
synchronized(Singleton.class){
if(_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
For example we have two threads A and B which try to execute getInstance() method simultaneously. Am I understand the process correctly:
Thread A enter into getInstance() method and acquire the lock;
Thread B also enter into getInstance() method and blocked;
Thread A create new Singleton() object and release the lock, now last value of _instance variable should be visible to thread B? Or thread B still could have own copy of _instance variable which is not synchronized with the main memory(_instance=null)?
Thread B is blocked on the synchronize, when it proceeds it will see the changed field _instance != null and therefore does not construct one but return the existing.
All other threads which come later see the instance being set and will not even lock.
Problem: your code is incomplete, you need volatile in order to make sure threads which do not go through the synchronized (most of them, hopefully) still only see a completely published singleton object.
The Java Memory Model does only guarantee that the final fields are initialized. For all others you need a safe publish, which is possible with:
Exchange the reference through a properly locked field (JLS 17.4.5)
Use static initializer to do the initializing stores (JLS 12.4)
Exchange the reference via a volatile field (JLS 17.4.5), or as the consequence of this rule, via the AtomicX classes
Initialize the value into a final field (JLS 17.5).
The easiest method to avoid the volatile (or an atomic reference which is also safe to publish objects to other threads) is to use normal Object initialisation, this is a valid and robust singleton (but not lazy) provided by the JVM:
class Singleton
{
private static final Singleton HIGHLANDER = new Singleton();
private Singleton() { } // not accessible
public static getSingleton() { return HIGHLANDER; }
}
JDK internally uses this similar construct with "Holder" objects to implement the same simple and robust pattern but in a lazy fashion:
class Singleton
{
private Singleton() { } // not accessible
private static Class LazyHolder {
private static final Singleton LAZY_HIGHLANDER = new Singleton();
}
public static Singleton getInstance() {
return LazyHolder.LAZY_HIGHLANDER;
}
}
Both methods do not require volatile variable access (which you need in DCL case) or synchronisation (it is implicitly done by the JVM which does the initialisation protected by a class lock).
What you show here is called double-checked locking.
The static variable belongs to the class, not the thread. Both threads will see the proper value, but it is possible that the compiler may optimize the reads such that the static variable is not checked both times. For this reason, you should declare the variable with the volatile keyword.
Please note that in versions of Java prior to version 5 this might not work correctly even with a volatile variable. It used to be possible for the assignment to assign a partially-constructed object to the variable. Now the constructor must return before the assignment can proceed. This will work correctly in any modern version Java.
Two problems that could exist as far as I know.
Thread B might or might not see the latest value.
Thread B might see a partially constructed object, incase there are a lot of things that the constructor does, and JVM decides to change the ordering of the code.
Making it volatile solves both problems, since it enforces the happens before relationship and stops JVM from re ordering the code execution, and updates the values in the other threads.
I have gone through a singleton design pattern in Java which is below mentioned. I am having trouble to understand how does the Synchronized keyword in the public static getter or accessor method prevent more than one object creation ?
If at all it is being called twice from two different classes Synchronized should make their calls Synchronized i.e. one after the other . How does it govern only one object creation?
Please explain in details and also check the comments if my assumptions about the modifiers are correct or not
class MySingleton
{
private static MySingleton singletonObj; //as it is private it cannot be referenced outside of this class
//and as it is static all the instances of this class share the same copy of this refrence variable
private MySingleton()
{
System.out.println("Welcome to a singleton design pattern");
System.out.println("Objects cannot be instantiated outside of this class");
}
public static synchronized MySingleton getASingletonObject()
{
if(singletonObj==null)
{
singletonObj=new MySingleton();
}
return singletonObj;
}
}
Help is much appreciated :)
Thanks
Your question is about the way it works: You have one instance not because of the synchronized, but because it is stored in a static variable, and is instancied only one time (with a lazy creation - checked by the if).
The synchronized ensure you that only one Thread will instanciate the object, and avoid a bug where many Threads could create duplicates.
Here is the other way to implement it, and i find it more simple, and as efficient:
public class Singleton
private static final Singleton instance=new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
Note: the only condition for using this kind of implementation is that your constructor (the new) should not throw any exception, and should only contain simple code like variable initialisation.
The purpose of the Singleton class is that there is at most one instance of it and, hence, all threads access that same object.
Supposing there are 'n' threads trying to access the getASingletonObject method.
Case I:If we don't synchronize the getASingletonObject method the following could happen:
1) Thread1 enters getASingletonObject()
2) Thread2 enters getASingletonObject()
3) Thread1 evaluates singletonObj == null to true
4) Thread2 evaluates singletonObj == null to true
5) Thread1 assigns singletonObj and returns
6) Thread2 *re*assigns singletonObj = new Singleton() and returns.
Now the threads both have a difference instance of the Singleton class which is what should have been prevented by this pattern.
Synchronizing prevents that both Threads can access the same block of code at the same time. So synchronization is needed in a multithreaded environment when you instantiate singleton classes.
Now assuming that multple threads will attempt to access the Singletons methods at the same time synchronization might be neccessary on those methods as well. Especially if they change data instead of only reading it this is true.
You´re not implementing correctly Singleton patter look my implementation.
class MySingleton
{
private MySingleton instance; //You dont need that you instance be static, inside your class you have all the access of the Instance once you call getInstance()
public static MySingleton getInstance(){
return instance;
}
private MySingleton()
{
System.out.println("Welcome to a singleton design pattern");
System.out.println("Objects cannot be instantiated outside of this class");
}
public static synchronized MySingleton getASingletonObject()
{
if(instance==null)
{
instance=new MySingleton();
}
return instance;
}
}
//About the synchronized you have to understand that is like a lock, where every time a thread is getting inside he is closing the method so nobody else can be inside and then there´s no possible that when a thread is in the line instance=new MySingleton(); but has not being executed for the VM another thread would be in if(instance==null) asking the VM and returning true.
As soon as the first tread is out of the method the lock is open and then other threads can get in. And then they will see that the instance is already created.
The synchronized keyword protects the singleton member variable (singletonObj in this case) from multithreaded access. This ensures that even if multiple threads are trying to create an object, only one is still being used.
Check this article: http://www.javaworld.com/article/2073352/core-java/simply-singleton.html for more explanation.
Wikipedia says:
In software engineering, the singleton pattern is a design pattern
that restricts the instantiation of a class to one object.
So you create singletonObj only one-time because when you call getASingletonObject() you check is singletonObj == null and if it's null, so you create a new object, if it's not null you get 'singletonObj' created before.
public static synchronized gives you confidence that this object have been created once, because static says that singletonObj have been created once for class, but not for concrete instance of object. And synchronized provides a concurrent access to getASingletonObject() and it's give you confidence that object singletonObj couldn't be created twice when different threads call your method simultaneously.